Integrated internal changes from Google
diff --git a/conformance/ConformanceJava.java b/conformance/ConformanceJava.java
index 43787ff..24d206c 100644
--- a/conformance/ConformanceJava.java
+++ b/conformance/ConformanceJava.java
@@ -1,8 +1,11 @@
-
-import com.google.protobuf.conformance.Conformance;
-import com.google.protobuf.util.JsonFormat;
-import com.google.protobuf.util.JsonFormat.TypeRegistry;
+import com.google.protobuf.ByteString;
+import com.google.protobuf.CodedInputStream;
 import com.google.protobuf.InvalidProtocolBufferException;
+import com.google.protobuf.conformance.Conformance;
+import com.google.protobuf.util.JsonFormat.TypeRegistry;
+import com.google.protobuf.util.JsonFormat;
+import java.io.IOException;
+import java.nio.ByteBuffer;
 
 class ConformanceJava {
   private int testCount = 0;
@@ -47,13 +50,182 @@
     writeToStdout(buf);
   }
 
+  private enum BinaryDecoder {
+    BYTE_STRING_DECODER() {
+      @Override
+      public Conformance.TestAllTypes parse(ByteString bytes)
+          throws InvalidProtocolBufferException {
+        return Conformance.TestAllTypes.parseFrom(bytes);
+      }
+    },
+    BYTE_ARRAY_DECODER() {
+      @Override
+      public Conformance.TestAllTypes parse(ByteString bytes)
+          throws InvalidProtocolBufferException {
+        return Conformance.TestAllTypes.parseFrom(bytes.toByteArray());
+      }
+    },
+    ARRAY_BYTE_BUFFER_DECODER() {
+      @Override
+      public Conformance.TestAllTypes parse(ByteString bytes)
+          throws InvalidProtocolBufferException {
+        ByteBuffer buffer = ByteBuffer.allocate(bytes.size());
+        bytes.copyTo(buffer);
+        buffer.flip();
+        try {
+          return Conformance.TestAllTypes.parseFrom(CodedInputStream.newInstance(buffer));
+        } catch (InvalidProtocolBufferException e) {
+          throw e;
+        } catch (IOException e) {
+          throw new RuntimeException(
+              "ByteString based ByteBuffer should not throw IOException.", e);
+        }
+      }
+    },
+    READONLY_ARRAY_BYTE_BUFFER_DECODER() {
+      @Override
+      public Conformance.TestAllTypes parse(ByteString bytes)
+          throws InvalidProtocolBufferException {
+        try {
+          return Conformance.TestAllTypes.parseFrom(
+              CodedInputStream.newInstance(bytes.asReadOnlyByteBuffer()));
+        } catch (InvalidProtocolBufferException e) {
+          throw e;
+        } catch (IOException e) {
+          throw new RuntimeException(
+              "ByteString based ByteBuffer should not throw IOException.", e);
+        }
+      }
+    },
+    DIRECT_BYTE_BUFFER_DECODER() {
+      @Override
+      public Conformance.TestAllTypes parse(ByteString bytes)
+          throws InvalidProtocolBufferException {
+        ByteBuffer buffer = ByteBuffer.allocateDirect(bytes.size());
+        bytes.copyTo(buffer);
+        buffer.flip();
+        try {
+          return Conformance.TestAllTypes.parseFrom(CodedInputStream.newInstance(buffer));
+        } catch (InvalidProtocolBufferException e) {
+          throw e;
+        } catch (IOException e) {
+          throw new RuntimeException(
+              "ByteString based ByteBuffer should not throw IOException.", e);
+        }
+      }
+    },
+    READONLY_DIRECT_BYTE_BUFFER_DECODER() {
+      @Override
+      public Conformance.TestAllTypes parse(ByteString bytes)
+          throws InvalidProtocolBufferException {
+        ByteBuffer buffer = ByteBuffer.allocateDirect(bytes.size());
+        bytes.copyTo(buffer);
+        buffer.flip();
+        try {
+          return Conformance.TestAllTypes.parseFrom(
+              CodedInputStream.newInstance(buffer.asReadOnlyBuffer()));
+        } catch (InvalidProtocolBufferException e) {
+          throw e;
+        } catch (IOException e) {
+          throw new RuntimeException(
+              "ByteString based ByteBuffer should not throw IOException.", e);
+        }
+      }
+    },
+    INPUT_STREAM_DECODER() {
+      @Override
+      public Conformance.TestAllTypes parse(ByteString bytes)
+          throws InvalidProtocolBufferException {
+        try {
+          return Conformance.TestAllTypes.parseFrom(bytes.newInput());
+        } catch (InvalidProtocolBufferException e) {
+          throw e;
+        } catch (IOException e) {
+          throw new RuntimeException(
+              "ByteString based InputStream should not throw IOException.", e);
+        }
+      }
+    };
+
+    public abstract Conformance.TestAllTypes parse(ByteString bytes)
+        throws InvalidProtocolBufferException;
+  }
+
+  private Conformance.TestAllTypes parseBinary(ByteString bytes)
+      throws InvalidProtocolBufferException {
+    Conformance.TestAllTypes[] messages =
+        new Conformance.TestAllTypes[BinaryDecoder.values().length];
+    InvalidProtocolBufferException[] exceptions =
+        new InvalidProtocolBufferException[BinaryDecoder.values().length];
+
+    boolean hasMessage = false;
+    boolean hasException = false;
+    for (int i = 0; i < BinaryDecoder.values().length; ++i) {
+      try {
+        messages[i] = BinaryDecoder.values()[i].parse(bytes);
+        hasMessage = true;
+      } catch (InvalidProtocolBufferException e) {
+        exceptions[i] = e;
+        hasException = true;
+      }
+    }
+
+    if (hasMessage && hasException) {
+      StringBuilder sb =
+          new StringBuilder("Binary decoders disagreed on whether the payload was valid.\n");
+      for (int i = 0; i < BinaryDecoder.values().length; ++i) {
+        sb.append(BinaryDecoder.values()[i].name());
+        if (messages[i] != null) {
+          sb.append(" accepted the payload.\n");
+        } else {
+          sb.append(" rejected the payload.\n");
+        }
+      }
+      throw new RuntimeException(sb.toString());
+    }
+
+    if (hasException) {
+      // We do not check if exceptions are equal. Different implementations may return different
+      // exception messages. Throw an arbitrary one out instead.
+      throw exceptions[0];
+    }
+
+    // Fast path comparing all the messages with the first message, assuming equality being
+    // symmetric and transitive.
+    boolean allEqual = true;
+    for (int i = 1; i < messages.length; ++i) {
+      if (!messages[0].equals(messages[i])) {
+        allEqual = false;
+        break;
+      }
+    }
+
+    // Slow path: compare and find out all unequal pairs.
+    if (!allEqual) {
+      StringBuilder sb = new StringBuilder();
+      for (int i = 0; i < messages.length - 1; ++i) {
+        for (int j = i + 1; j < messages.length; ++j) {
+          if (!messages[i].equals(messages[j])) {
+            sb.append(BinaryDecoder.values()[i].name())
+                .append(" and ")
+                .append(BinaryDecoder.values()[j].name())
+                .append(" parsed the payload differently.\n");
+          }
+        }
+      }
+      throw new RuntimeException(sb.toString());
+    }
+
+    return messages[0];
+  }
+
   private Conformance.ConformanceResponse doTest(Conformance.ConformanceRequest request) {
     Conformance.TestAllTypes testMessage;
 
     switch (request.getPayloadCase()) {
       case PROTOBUF_PAYLOAD: {
         try {
-          testMessage = Conformance.TestAllTypes.parseFrom(request.getProtobufPayload());
+          testMessage = parseBinary(request.getProtobufPayload());
         } catch (InvalidProtocolBufferException e) {
           return Conformance.ConformanceResponse.newBuilder().setParseError(e.getMessage()).build();
         }
diff --git a/conformance/conformance_test.cc b/conformance/conformance_test.cc
index b74122c..e709ac8 100644
--- a/conformance/conformance_test.cc
+++ b/conformance/conformance_test.cc
@@ -685,7 +685,7 @@
       R"({
         "fieldname1": 1,
         "fieldName2": 2,
-        "fieldName3": 3,
+        "FieldName3": 3,
         "fieldName4": 4
       })",
       R"(
@@ -725,12 +725,12 @@
   RunValidJsonTest(
       "FieldNameWithDoubleUnderscores", RECOMMENDED,
       R"({
-        "fieldName13": 13,
-        "fieldName14": 14,
+        "FieldName13": 13,
+        "FieldName14": 14,
         "fieldName15": 15,
         "fieldName16": 16,
         "fieldName17": 17,
-        "fieldName18": 18
+        "FieldName18": 18
       })",
       R"(
         __field_name13: 13
@@ -873,21 +873,19 @@
         "optionalNestedMessage": {a: 1},
         "optional_nested_message": {}
       })");
-  // NOTE: The spec for JSON support is still being sorted out, these may not
-  // all be correct.
   // Serializers should use lowerCamelCase by default.
   RunValidJsonTestWithValidator(
       "FieldNameInLowerCamelCase", REQUIRED,
       R"({
         "fieldname1": 1,
         "fieldName2": 2,
-        "fieldName3": 3,
+        "FieldName3": 3,
         "fieldName4": 4
       })",
       [](const Json::Value& value) {
         return value.isMember("fieldname1") &&
             value.isMember("fieldName2") &&
-            value.isMember("fieldName3") &&
+            value.isMember("FieldName3") &&
             value.isMember("fieldName4");
       });
   RunValidJsonTestWithValidator(
@@ -921,20 +919,20 @@
   RunValidJsonTestWithValidator(
       "FieldNameWithDoubleUnderscores", RECOMMENDED,
       R"({
-        "fieldName13": 13,
-        "fieldName14": 14,
+        "FieldName13": 13,
+        "FieldName14": 14,
         "fieldName15": 15,
         "fieldName16": 16,
         "fieldName17": 17,
-        "fieldName18": 18
+        "FieldName18": 18
       })",
       [](const Json::Value& value) {
-        return value.isMember("fieldName13") &&
-            value.isMember("fieldName14") &&
+        return value.isMember("FieldName13") &&
+            value.isMember("FieldName14") &&
             value.isMember("fieldName15") &&
             value.isMember("fieldName16") &&
             value.isMember("fieldName17") &&
-            value.isMember("fieldName18");
+            value.isMember("FieldName18");
       });
 
   // Integer fields.
diff --git a/conformance/failure_list_cpp.txt b/conformance/failure_list_cpp.txt
index 508be50..8cfd74d 100644
--- a/conformance/failure_list_cpp.txt
+++ b/conformance/failure_list_cpp.txt
@@ -17,9 +17,6 @@
 Recommended.JsonInput.FieldNameDuplicateDifferentCasing1
 Recommended.JsonInput.FieldNameDuplicateDifferentCasing2
 Recommended.JsonInput.FieldNameNotQuoted
-Recommended.JsonInput.FieldNameWithDoubleUnderscores.JsonOutput
-Recommended.JsonInput.FieldNameWithDoubleUnderscores.ProtobufOutput
-Recommended.JsonInput.FieldNameWithDoubleUnderscores.Validator
 Recommended.JsonInput.MapFieldValueIsNull
 Recommended.JsonInput.RepeatedFieldMessageElementIsNull
 Recommended.JsonInput.RepeatedFieldPrimitiveElementIsNull
@@ -35,10 +32,6 @@
 Recommended.JsonInput.TrailingCommaInAnObjectWithNewlines
 Recommended.JsonInput.TrailingCommaInAnObjectWithSpace
 Recommended.JsonInput.TrailingCommaInAnObjectWithSpaceCommaSpace
-Required.JsonInput.DoubleFieldTooSmall
-Required.JsonInput.FieldNameInLowerCamelCase.Validator
-Required.JsonInput.FieldNameInSnakeCase.JsonOutput
-Required.JsonInput.FieldNameInSnakeCase.ProtobufOutput
 Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.MESSAGE
 Required.ProtobufInput.PrematureEofInDelimitedDataForKnownNonRepeatedValue.MESSAGE
 Required.ProtobufInput.PrematureEofInDelimitedDataForKnownRepeatedValue.MESSAGE
diff --git a/conformance/failure_list_java.txt b/conformance/failure_list_java.txt
index c9007d6..a4f0f10 100644
--- a/conformance/failure_list_java.txt
+++ b/conformance/failure_list_java.txt
@@ -20,9 +20,6 @@
 Recommended.JsonInput.FieldMaskInvalidCharacter
 Recommended.JsonInput.FieldNameDuplicate
 Recommended.JsonInput.FieldNameNotQuoted
-Recommended.JsonInput.FieldNameWithDoubleUnderscores.JsonOutput
-Recommended.JsonInput.FieldNameWithDoubleUnderscores.ProtobufOutput
-Recommended.JsonInput.FieldNameWithDoubleUnderscores.Validator
 Recommended.JsonInput.FloatFieldInfinityNotQuoted
 Recommended.JsonInput.FloatFieldNanNotQuoted
 Recommended.JsonInput.FloatFieldNegativeInfinityNotQuoted
@@ -35,15 +32,15 @@
 Recommended.JsonInput.StringFieldSurrogateInWrongOrder
 Recommended.JsonInput.StringFieldUnpairedHighSurrogate
 Recommended.JsonInput.StringFieldUnpairedLowSurrogate
+Recommended.JsonInput.StringFieldUppercaseEscapeLetter
 Recommended.JsonInput.Uint32MapFieldKeyNotQuoted
 Recommended.JsonInput.Uint64MapFieldKeyNotQuoted
 Required.JsonInput.EnumFieldNotQuoted
-Required.JsonInput.FieldNameInLowerCamelCase.Validator
-Required.JsonInput.FieldNameInSnakeCase.JsonOutput
-Required.JsonInput.FieldNameInSnakeCase.ProtobufOutput
 Required.JsonInput.Int32FieldLeadingZero
 Required.JsonInput.Int32FieldNegativeWithLeadingZero
 Required.JsonInput.Int32FieldPlusSign
 Required.JsonInput.RepeatedFieldWrongElementTypeExpectingStringsGotBool
 Required.JsonInput.RepeatedFieldWrongElementTypeExpectingStringsGotInt
 Required.JsonInput.StringFieldNotAString
+Required.ProtobufInput.PrematureEofInDelimitedDataForKnownNonRepeatedValue.MESSAGE
+Required.ProtobufInput.PrematureEofInDelimitedDataForKnownRepeatedValue.MESSAGE
diff --git a/conformance/failure_list_python.txt b/conformance/failure_list_python.txt
index 0498519..9d556a0 100644
--- a/conformance/failure_list_python.txt
+++ b/conformance/failure_list_python.txt
@@ -1,18 +1,12 @@
 Recommended.JsonInput.DoubleFieldInfinityNotQuoted
 Recommended.JsonInput.DoubleFieldNanNotQuoted
 Recommended.JsonInput.DoubleFieldNegativeInfinityNotQuoted
-Recommended.JsonInput.FieldNameWithDoubleUnderscores.JsonOutput
-Recommended.JsonInput.FieldNameWithDoubleUnderscores.ProtobufOutput
-Recommended.JsonInput.FieldNameWithDoubleUnderscores.Validator
 Recommended.JsonInput.FloatFieldInfinityNotQuoted
 Recommended.JsonInput.FloatFieldNanNotQuoted
 Recommended.JsonInput.FloatFieldNegativeInfinityNotQuoted
 Required.JsonInput.BytesFieldInvalidBase64Characters
 Required.JsonInput.DoubleFieldTooSmall
 Required.JsonInput.EnumFieldUnknownValue.Validator
-Required.JsonInput.FieldNameInLowerCamelCase.Validator
-Required.JsonInput.FieldNameInSnakeCase.JsonOutput
-Required.JsonInput.FieldNameInSnakeCase.ProtobufOutput
 Required.JsonInput.FloatFieldTooLarge
 Required.JsonInput.FloatFieldTooSmall
 Required.JsonInput.RepeatedFieldWrongElementTypeExpectingIntegersGotBool
diff --git a/conformance/failure_list_python_cpp.txt b/conformance/failure_list_python_cpp.txt
index f3958f5..92404d2 100644
--- a/conformance/failure_list_python_cpp.txt
+++ b/conformance/failure_list_python_cpp.txt
@@ -10,18 +10,12 @@
 Recommended.JsonInput.DoubleFieldInfinityNotQuoted
 Recommended.JsonInput.DoubleFieldNanNotQuoted
 Recommended.JsonInput.DoubleFieldNegativeInfinityNotQuoted
-Recommended.JsonInput.FieldNameWithDoubleUnderscores.JsonOutput
-Recommended.JsonInput.FieldNameWithDoubleUnderscores.ProtobufOutput
-Recommended.JsonInput.FieldNameWithDoubleUnderscores.Validator
 Recommended.JsonInput.FloatFieldInfinityNotQuoted
 Recommended.JsonInput.FloatFieldNanNotQuoted
 Recommended.JsonInput.FloatFieldNegativeInfinityNotQuoted
 Required.JsonInput.BytesFieldInvalidBase64Characters
 Required.JsonInput.DoubleFieldTooSmall
 Required.JsonInput.EnumFieldUnknownValue.Validator
-Required.JsonInput.FieldNameInLowerCamelCase.Validator
-Required.JsonInput.FieldNameInSnakeCase.JsonOutput
-Required.JsonInput.FieldNameInSnakeCase.ProtobufOutput
 Required.JsonInput.FloatFieldTooLarge
 Required.JsonInput.FloatFieldTooSmall
 Required.JsonInput.RepeatedFieldWrongElementTypeExpectingIntegersGotBool