Coded*Stream streamlining.

Remove ICodedInputStream and ICodedOutputStream, and rewrite CodedInputStream and CodedOutputStream to be specific to the binary format. If we want to support text-based formats, that can be a whole different serialization mechanism.
diff --git a/csharp/src/ProtocolBuffers.Test/CodedInputStreamTest.cs b/csharp/src/ProtocolBuffers.Test/CodedInputStreamTest.cs
index aa2da33..450662a 100644
--- a/csharp/src/ProtocolBuffers.Test/CodedInputStreamTest.cs
+++ b/csharp/src/ProtocolBuffers.Test/CodedInputStreamTest.cs
@@ -336,13 +336,11 @@
 

             CodedInputStream input = CodedInputStream.CreateInstance(ms);

             uint testtag;

-            string ignore;

-            Assert.IsTrue(input.ReadTag(out testtag, out ignore));

+            Assert.IsTrue(input.ReadTag(out testtag));

             Assert.AreEqual(tag, testtag);

 

-            ByteString bytes = null;

             // TODO(jonskeet): Should this be ArgumentNullException instead?

-            Assert.Throws<InvalidProtocolBufferException>(() => input.ReadBytes(ref bytes));

+            Assert.Throws<InvalidProtocolBufferException>(() => input.ReadBytes());

         }

 

         private static TestRecursiveMessage MakeRecursiveMessage(int depth)

@@ -435,13 +433,10 @@
 

             CodedInputStream input = CodedInputStream.CreateInstance(ms);

 

-            uint testtag;

-            string ignored;

-

-            Assert.IsTrue(input.ReadTag(out testtag, out ignored));

-            Assert.AreEqual(tag, testtag);

-            string text = null;

-            input.ReadString(ref text);

+            uint actualTag;

+            Assert.IsTrue(input.ReadTag(out actualTag));

+            Assert.AreEqual(tag, actualTag);

+            string text = input.ReadString();

             Assert.AreEqual('\ufffd', text[0]);

         }

 

@@ -473,11 +468,8 @@
         {

             byte[] bytes = new byte[10] { 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01 };

             CodedInputStream input = CodedInputStream.CreateInstance(bytes);

-            int val = 0;

-

-            Assert.IsTrue(input.ReadEnum(ref val));

+            Assert.AreEqual((int)TestNegEnum.Value, input.ReadEnum());

             Assert.IsTrue(input.IsAtEnd);

-            Assert.AreEqual((int) TestNegEnum.Value, val);

         }

 

         [Test]

@@ -487,17 +479,16 @@
             int msgSize = 1 + 1 + arraySize;

             byte[] bytes = new byte[msgSize];

             CodedOutputStream output = CodedOutputStream.CreateInstance(bytes);

-            output.WritePackedInt32Array(8, "", new RepeatedField<int> { 0, -1, -2, -3, -4, -5 });

+            output.WritePackedInt32Array(8, new RepeatedField<int> { 0, -1, -2, -3, -4, -5 });

 

             Assert.AreEqual(0, output.SpaceLeft);

 

             CodedInputStream input = CodedInputStream.CreateInstance(bytes);

             uint tag;

-            string name;

-            Assert.IsTrue(input.ReadTag(out tag, out name));

+            Assert.IsTrue(input.ReadTag(out tag));

 

             List<TestNegEnum> values = new List<TestNegEnum>();

-            input.ReadEnumArray(tag, name, values);

+            input.ReadEnumArray(tag, values);

 

             Assert.AreEqual(6, values.Count);

             Assert.AreEqual(TestNegEnum.None, values[0]);

@@ -512,17 +503,16 @@
             int msgSize = arraySize;

             byte[] bytes = new byte[msgSize];

             CodedOutputStream output = CodedOutputStream.CreateInstance(bytes);

-            output.WriteInt32Array(8, "", new RepeatedField<int> { 0, -1, -2, -3, -4, -5 });

+            output.WriteInt32Array(8, new RepeatedField<int> { 0, -1, -2, -3, -4, -5 });

 

             Assert.AreEqual(0, output.SpaceLeft);

 

             CodedInputStream input = CodedInputStream.CreateInstance(bytes);

             uint tag;

-            string name;

-            Assert.IsTrue(input.ReadTag(out tag, out name));

+            Assert.IsTrue(input.ReadTag(out tag));

 

             List<TestNegEnum> values = new List<TestNegEnum>();

-            input.ReadEnumArray(tag, name, values);

+            input.ReadEnumArray(tag, values);

 

             Assert.AreEqual(6, values.Count);

             Assert.AreEqual(TestNegEnum.None, values[0]);

@@ -537,26 +527,21 @@
             using (var ms = new MemoryStream())

             {

                 CodedOutputStream output = CodedOutputStream.CreateInstance(ms);

-                output.WriteField(FieldType.Bytes, 1, "bytes", ByteString.CopyFrom(new byte[100]));

-                output.WriteField(FieldType.Bytes, 2, "bytes", ByteString.CopyFrom(new byte[100]));

+                output.WriteBytes(1, ByteString.CopyFrom(new byte[100]));

+                output.WriteBytes(2, ByteString.CopyFrom(new byte[100]));

                 output.Flush();

 

                 ms.Position = 0;

                 CodedInputStream input = CodedInputStream.CreateInstance(ms, new byte[ms.Length / 2]);

 

                 uint tag;

-                string ignore;

-                ByteString value;

-

-                Assert.IsTrue(input.ReadTag(out tag, out ignore));

+                Assert.IsTrue(input.ReadTag(out tag));

                 Assert.AreEqual(1, WireFormat.GetTagFieldNumber(tag));

-                value = ByteString.Empty;

-                Assert.IsTrue(input.ReadBytes(ref value) && value.Length == 100);

+                Assert.AreEqual(100, input.ReadBytes().Length);

 

-                Assert.IsTrue(input.ReadTag(out tag, out ignore));

+                Assert.IsTrue(input.ReadTag(out tag));

                 Assert.AreEqual(2, WireFormat.GetTagFieldNumber(tag));

-                value = ByteString.Empty;

-                Assert.IsTrue(input.ReadBytes(ref value) && value.Length == 100);

+                Assert.AreEqual(100, input.ReadBytes().Length);

             }

         }

     }

diff --git a/csharp/src/ProtocolBuffers.Test/CodedOutputStreamTest.cs b/csharp/src/ProtocolBuffers.Test/CodedOutputStreamTest.cs
index fcbb7f8..682c005 100644
--- a/csharp/src/ProtocolBuffers.Test/CodedOutputStreamTest.cs
+++ b/csharp/src/ProtocolBuffers.Test/CodedOutputStreamTest.cs
@@ -316,7 +316,7 @@
 

             byte[] bytes = new byte[11];

             CodedOutputStream output = CodedOutputStream.CreateInstance(bytes);

-            output.WriteEnum(8, "", (int) TestNegEnum.Value);

+            output.WriteEnum(8, (int) TestNegEnum.Value);

 

             Assert.AreEqual(0, output.SpaceLeft);

             //fyi, 0x40 == 0x08 << 3 + 0, field num + wire format shift

@@ -330,18 +330,17 @@
             int msgSize = 1 + 1 + arraySize;

             byte[] bytes = new byte[msgSize];

             CodedOutputStream output = CodedOutputStream.CreateInstance(bytes);

-            output.WritePackedEnumArray(8, "", new RepeatedField<TestNegEnum> {

+            output.WritePackedEnumArray(8, new RepeatedField<TestNegEnum> {

                 0, (TestNegEnum) (-1), TestNegEnum.Value, (TestNegEnum) (-3), (TestNegEnum) (-4), (TestNegEnum) (-5) });

 

             Assert.AreEqual(0, output.SpaceLeft);

 

             CodedInputStream input = CodedInputStream.CreateInstance(bytes);

             uint tag;

-            string name;

-            Assert.IsTrue(input.ReadTag(out tag, out name));

+            Assert.IsTrue(input.ReadTag(out tag));

 

             List<int> values = new List<int>();

-            input.ReadInt32Array(tag, name, values);

+            input.ReadInt32Array(tag, values);

 

             Assert.AreEqual(6, values.Count);

             for (int i = 0; i > -6; i--)

@@ -355,17 +354,16 @@
             int msgSize = arraySize;

             byte[] bytes = new byte[msgSize];

             CodedOutputStream output = CodedOutputStream.CreateInstance(bytes);

-            output.WriteEnumArray(8, "", new RepeatedField<TestNegEnum> {

+            output.WriteEnumArray(8, new RepeatedField<TestNegEnum> {

                 0, (TestNegEnum) (-1), TestNegEnum.Value, (TestNegEnum) (-3), (TestNegEnum) (-4), (TestNegEnum) (-5) });

             Assert.AreEqual(0, output.SpaceLeft);

 

             CodedInputStream input = CodedInputStream.CreateInstance(bytes);

             uint tag;

-            string name;

-            Assert.IsTrue(input.ReadTag(out tag, out name));

+            Assert.IsTrue(input.ReadTag(out tag));

 

             List<int> values = new List<int>();

-            input.ReadInt32Array(tag, name, values);

+            input.ReadInt32Array(tag, values);

 

             Assert.AreEqual(6, values.Count);

             for (int i = 0; i > -6; i--)

@@ -425,16 +423,14 @@
             {

                 CodedInputStream cin = CodedInputStream.CreateInstance(new MemoryStream(bytes), new byte[50]);

                 uint tag;

-                int intValue = 0;

-                string ignore;

                 Assert.AreEqual(0, cin.Position);

                 // Field 1:

-                Assert.IsTrue(cin.ReadTag(out tag, out ignore) && tag >> 3 == 1);

+                Assert.IsTrue(cin.ReadTag(out tag) && tag >> 3 == 1);

                 Assert.AreEqual(1, cin.Position);

-                Assert.IsTrue(cin.ReadInt32(ref intValue) && intValue == 500);

+                Assert.AreEqual(500, cin.ReadInt32());

                 Assert.AreEqual(3, cin.Position);

                 //Field 2:

-                Assert.IsTrue(cin.ReadTag(out tag, out ignore) && tag >> 3 == 2);

+                Assert.IsTrue(cin.ReadTag(out tag) && tag >> 3 == 2);

                 Assert.AreEqual(4, cin.Position);

                 uint childlen = cin.ReadRawVarint32();

                 Assert.AreEqual(120u, childlen);

@@ -444,30 +440,31 @@
                 // Now we are reading child message

                 {

                     // Field 11: numeric value: 500

-                    Assert.IsTrue(cin.ReadTag(out tag, out ignore) && tag >> 3 == 11);

+                    Assert.IsTrue(cin.ReadTag(out tag) && tag >> 3 == 11);

                     Assert.AreEqual(6, cin.Position);

-                    Assert.IsTrue(cin.ReadInt32(ref intValue) && intValue == 500);

+                    Assert.AreEqual(500, cin.ReadInt32());

                     Assert.AreEqual(8, cin.Position);

                     //Field 12: length delimited 120 bytes

-                    Assert.IsTrue(cin.ReadTag(out tag, out ignore) && tag >> 3 == 12);

+                    Assert.IsTrue(cin.ReadTag(out tag) && tag >> 3 == 12);

                     Assert.AreEqual(9, cin.Position);

-                    ByteString bstr = null;

-                    Assert.IsTrue(cin.ReadBytes(ref bstr) && bstr.Length == 110 && bstr.ToByteArray()[109] == 109);

+                    ByteString bstr = cin.ReadBytes();

+                    Assert.AreEqual(110, bstr.Length);

+                    Assert.AreEqual((byte) 109, bstr[109]);

                     Assert.AreEqual(120, cin.Position);

                     // Field 13: fixed numeric value: 501

-                    Assert.IsTrue(cin.ReadTag(out tag, out ignore) && tag >> 3 == 13);

+                    Assert.IsTrue(cin.ReadTag(out tag) && tag >> 3 == 13);

                     // ROK - Previously broken here, this returned 126 failing to account for bufferSizeAfterLimit

                     Assert.AreEqual(121, cin.Position);

-                    Assert.IsTrue(cin.ReadSFixed32(ref intValue) && intValue == 501);

+                    Assert.AreEqual(501, cin.ReadSFixed32());

                     Assert.AreEqual(125, cin.Position);

                     Assert.IsTrue(cin.IsAtEnd);

                 }

                 cin.PopLimit(oldlimit);

                 Assert.AreEqual(125, cin.Position);

                 // Field 3: fixed numeric value: 501

-                Assert.IsTrue(cin.ReadTag(out tag, out ignore) && tag >> 3 == 3);

+                Assert.IsTrue(cin.ReadTag(out tag) && tag >> 3 == 3);

                 Assert.AreEqual(126, cin.Position);

-                Assert.IsTrue(cin.ReadSFixed32(ref intValue) && intValue == 501);

+                Assert.AreEqual(501, cin.ReadSFixed32());

                 Assert.AreEqual(130, cin.Position);

                 Assert.IsTrue(cin.IsAtEnd);

             }

diff --git a/csharp/src/ProtocolBuffers.Test/TestProtos/UnittestImportProto3.cs b/csharp/src/ProtocolBuffers.Test/TestProtos/UnittestImportProto3.cs
index 4b62794..1bd4e22 100644
--- a/csharp/src/ProtocolBuffers.Test/TestProtos/UnittestImportProto3.cs
+++ b/csharp/src/ProtocolBuffers.Test/TestProtos/UnittestImportProto3.cs
@@ -107,10 +107,9 @@
       return hash;
     }
 
-    public void WriteTo(pb::ICodedOutputStream output) {
-      string[] fieldNames = _fieldNames;
+    public void WriteTo(pb::CodedOutputStream output) {
       if (D != 0) {
-        output.WriteInt32(1, fieldNames[0], D);
+        output.WriteInt32(1, D);
       }
     }
 
@@ -130,16 +129,9 @@
       }
     }
 
-    public void MergeFrom(pb::ICodedInputStream input) {
+    public void MergeFrom(pb::CodedInputStream input) {
       uint tag;
-      string fieldName;
-      while (input.ReadTag(out tag, out fieldName)) {
-        if (tag == 0 && fieldName != null) {
-          int fieldOrdinal = global::System.Array.BinarySearch(_fieldNames, fieldName, global::System.StringComparer.Ordinal);
-          if (fieldOrdinal >= 0) {
-            tag = _fieldTags[fieldOrdinal];
-          }
-        }
+      while (input.ReadTag(out tag)) {
         switch(tag) {
           case 0:
             throw pb::InvalidProtocolBufferException.InvalidTag();
@@ -149,7 +141,7 @@
             }
             break;
           case 8: {
-            input.ReadInt32(ref d_);
+            d_ = input.ReadInt32();
             break;
           }
         }
diff --git a/csharp/src/ProtocolBuffers.Test/TestProtos/UnittestImportPublicProto3.cs b/csharp/src/ProtocolBuffers.Test/TestProtos/UnittestImportPublicProto3.cs
index 2f7f869..32123d5 100644
--- a/csharp/src/ProtocolBuffers.Test/TestProtos/UnittestImportPublicProto3.cs
+++ b/csharp/src/ProtocolBuffers.Test/TestProtos/UnittestImportPublicProto3.cs
@@ -92,10 +92,9 @@
       return hash;
     }
 
-    public void WriteTo(pb::ICodedOutputStream output) {
-      string[] fieldNames = _fieldNames;
+    public void WriteTo(pb::CodedOutputStream output) {
       if (E != 0) {
-        output.WriteInt32(1, fieldNames[0], E);
+        output.WriteInt32(1, E);
       }
     }
 
@@ -115,16 +114,9 @@
       }
     }
 
-    public void MergeFrom(pb::ICodedInputStream input) {
+    public void MergeFrom(pb::CodedInputStream input) {
       uint tag;
-      string fieldName;
-      while (input.ReadTag(out tag, out fieldName)) {
-        if (tag == 0 && fieldName != null) {
-          int fieldOrdinal = global::System.Array.BinarySearch(_fieldNames, fieldName, global::System.StringComparer.Ordinal);
-          if (fieldOrdinal >= 0) {
-            tag = _fieldTags[fieldOrdinal];
-          }
-        }
+      while (input.ReadTag(out tag)) {
         switch(tag) {
           case 0:
             throw pb::InvalidProtocolBufferException.InvalidTag();
@@ -134,7 +126,7 @@
             }
             break;
           case 8: {
-            input.ReadInt32(ref e_);
+            e_ = input.ReadInt32();
             break;
           }
         }
diff --git a/csharp/src/ProtocolBuffers.Test/TestProtos/UnittestIssues.cs b/csharp/src/ProtocolBuffers.Test/TestProtos/UnittestIssues.cs
index 14ca78a..d8c8995 100644
--- a/csharp/src/ProtocolBuffers.Test/TestProtos/UnittestIssues.cs
+++ b/csharp/src/ProtocolBuffers.Test/TestProtos/UnittestIssues.cs
@@ -153,13 +153,12 @@
       return hash;
     }
 
-    public void WriteTo(pb::ICodedOutputStream output) {
-      string[] fieldNames = _fieldNames;
+    public void WriteTo(pb::CodedOutputStream output) {
       if (Value != global::UnitTest.Issues.TestProtos.NegativeEnum.NEGATIVE_ENUM_ZERO) {
-        output.WriteEnum(1, fieldNames[1], (int) Value);
+        output.WriteEnum(1, (int) Value);
       }
-      output.WriteEnumArray(2, fieldNames[2], values_);
-      output.WritePackedEnumArray(3, fieldNames[0], packedValues_);
+      output.WriteEnumArray(2, values_);
+      output.WritePackedEnumArray(3, packedValues_);
     }
 
     public int CalculateSize() {
@@ -201,16 +200,9 @@
       packedValues_.Add(other.packedValues_);
     }
 
-    public void MergeFrom(pb::ICodedInputStream input) {
+    public void MergeFrom(pb::CodedInputStream input) {
       uint tag;
-      string fieldName;
-      while (input.ReadTag(out tag, out fieldName)) {
-        if (tag == 0 && fieldName != null) {
-          int fieldOrdinal = global::System.Array.BinarySearch(_fieldNames, fieldName, global::System.StringComparer.Ordinal);
-          if (fieldOrdinal >= 0) {
-            tag = _fieldTags[fieldOrdinal];
-          }
-        }
+      while (input.ReadTag(out tag)) {
         switch(tag) {
           case 0:
             throw pb::InvalidProtocolBufferException.InvalidTag();
@@ -220,18 +212,17 @@
             }
             break;
           case 8: {
-            int tmp = 0;
-            input.ReadEnum(ref tmp);
-            value_ = (global::UnitTest.Issues.TestProtos.NegativeEnum) tmp;break;
+            value_ = (global::UnitTest.Issues.TestProtos.NegativeEnum) input.ReadEnum();
+            break;
           }
           case 18:
           case 16: {
-            input.ReadEnumArray<global::UnitTest.Issues.TestProtos.NegativeEnum>(tag, fieldName, values_);
+            input.ReadEnumArray<global::UnitTest.Issues.TestProtos.NegativeEnum>(tag, values_);
             break;
           }
           case 26:
           case 24: {
-            input.ReadEnumArray<global::UnitTest.Issues.TestProtos.NegativeEnum>(tag, fieldName, packedValues_);
+            input.ReadEnumArray<global::UnitTest.Issues.TestProtos.NegativeEnum>(tag, packedValues_);
             break;
           }
         }
@@ -278,8 +269,7 @@
       return hash;
     }
 
-    public void WriteTo(pb::ICodedOutputStream output) {
-      string[] fieldNames = _fieldNames;
+    public void WriteTo(pb::CodedOutputStream output) {
     }
 
     public int CalculateSize() {
@@ -292,16 +282,9 @@
       }
     }
 
-    public void MergeFrom(pb::ICodedInputStream input) {
+    public void MergeFrom(pb::CodedInputStream input) {
       uint tag;
-      string fieldName;
-      while (input.ReadTag(out tag, out fieldName)) {
-        if (tag == 0 && fieldName != null) {
-          int fieldOrdinal = global::System.Array.BinarySearch(_fieldNames, fieldName, global::System.StringComparer.Ordinal);
-          if (fieldOrdinal >= 0) {
-            tag = _fieldTags[fieldOrdinal];
-          }
-        }
+      while (input.ReadTag(out tag)) {
         switch(tag) {
           case 0:
             throw pb::InvalidProtocolBufferException.InvalidTag();
@@ -412,20 +395,19 @@
       return hash;
     }
 
-    public void WriteTo(pb::ICodedOutputStream output) {
-      string[] fieldNames = _fieldNames;
+    public void WriteTo(pb::CodedOutputStream output) {
       if (PrimitiveValue != 0) {
-        output.WriteInt32(1, fieldNames[5], PrimitiveValue);
+        output.WriteInt32(1, PrimitiveValue);
       }
-      output.WritePackedInt32Array(2, fieldNames[4], primitiveArray_);
+      output.WritePackedInt32Array(2, primitiveArray_);
       if (messageValue_ != null) {
-        output.WriteMessage(3, fieldNames[3], MessageValue);
+        output.WriteMessage(3, MessageValue);
       }
-      output.WriteMessageArray(4, fieldNames[2], messageArray_);
+      output.WriteMessageArray(4, messageArray_);
       if (EnumValue != global::UnitTest.Issues.TestProtos.DeprecatedEnum.DEPRECATED_ZERO) {
-        output.WriteEnum(5, fieldNames[1], (int) EnumValue);
+        output.WriteEnum(5, (int) EnumValue);
       }
-      output.WritePackedEnumArray(6, fieldNames[0], enumArray_);
+      output.WritePackedEnumArray(6, enumArray_);
     }
 
     public int CalculateSize() {
@@ -486,16 +468,9 @@
       enumArray_.Add(other.enumArray_);
     }
 
-    public void MergeFrom(pb::ICodedInputStream input) {
+    public void MergeFrom(pb::CodedInputStream input) {
       uint tag;
-      string fieldName;
-      while (input.ReadTag(out tag, out fieldName)) {
-        if (tag == 0 && fieldName != null) {
-          int fieldOrdinal = global::System.Array.BinarySearch(_fieldNames, fieldName, global::System.StringComparer.Ordinal);
-          if (fieldOrdinal >= 0) {
-            tag = _fieldTags[fieldOrdinal];
-          }
-        }
+      while (input.ReadTag(out tag)) {
         switch(tag) {
           case 0:
             throw pb::InvalidProtocolBufferException.InvalidTag();
@@ -505,12 +480,12 @@
             }
             break;
           case 8: {
-            input.ReadInt32(ref primitiveValue_);
+            primitiveValue_ = input.ReadInt32();
             break;
           }
           case 18:
           case 16: {
-            input.ReadInt32Array(tag, fieldName, primitiveArray_);
+            input.ReadInt32Array(tag, primitiveArray_);
             break;
           }
           case 26: {
@@ -521,17 +496,16 @@
             break;
           }
           case 34: {
-            input.ReadMessageArray(tag, fieldName, messageArray_, global::UnitTest.Issues.TestProtos.DeprecatedChild.Parser);
+            input.ReadMessageArray(tag, messageArray_, global::UnitTest.Issues.TestProtos.DeprecatedChild.Parser);
             break;
           }
           case 40: {
-            int tmp = 0;
-            input.ReadEnum(ref tmp);
-            enumValue_ = (global::UnitTest.Issues.TestProtos.DeprecatedEnum) tmp;break;
+            enumValue_ = (global::UnitTest.Issues.TestProtos.DeprecatedEnum) input.ReadEnum();
+            break;
           }
           case 50:
           case 48: {
-            input.ReadEnumArray<global::UnitTest.Issues.TestProtos.DeprecatedEnum>(tag, fieldName, enumArray_);
+            input.ReadEnumArray<global::UnitTest.Issues.TestProtos.DeprecatedEnum>(tag, enumArray_);
             break;
           }
         }
@@ -588,10 +562,9 @@
       return hash;
     }
 
-    public void WriteTo(pb::ICodedOutputStream output) {
-      string[] fieldNames = _fieldNames;
+    public void WriteTo(pb::CodedOutputStream output) {
       if (Item != 0) {
-        output.WriteInt32(1, fieldNames[0], Item);
+        output.WriteInt32(1, Item);
       }
     }
 
@@ -611,16 +584,9 @@
       }
     }
 
-    public void MergeFrom(pb::ICodedInputStream input) {
+    public void MergeFrom(pb::CodedInputStream input) {
       uint tag;
-      string fieldName;
-      while (input.ReadTag(out tag, out fieldName)) {
-        if (tag == 0 && fieldName != null) {
-          int fieldOrdinal = global::System.Array.BinarySearch(_fieldNames, fieldName, global::System.StringComparer.Ordinal);
-          if (fieldOrdinal >= 0) {
-            tag = _fieldTags[fieldOrdinal];
-          }
-        }
+      while (input.ReadTag(out tag)) {
         switch(tag) {
           case 0:
             throw pb::InvalidProtocolBufferException.InvalidTag();
@@ -630,7 +596,7 @@
             }
             break;
           case 8: {
-            input.ReadInt32(ref item_);
+            item_ = input.ReadInt32();
             break;
           }
         }
diff --git a/csharp/src/ProtocolBuffers.Test/TestProtos/UnittestProto3.cs b/csharp/src/ProtocolBuffers.Test/TestProtos/UnittestProto3.cs
index 3e5bb8b..4c4daba 100644
--- a/csharp/src/ProtocolBuffers.Test/TestProtos/UnittestProto3.cs
+++ b/csharp/src/ProtocolBuffers.Test/TestProtos/UnittestProto3.cs
@@ -888,107 +888,106 @@
       return hash;
     }
 
-    public void WriteTo(pb::ICodedOutputStream output) {
-      string[] fieldNames = _fieldNames;
+    public void WriteTo(pb::CodedOutputStream output) {
       if (SingleInt32 != 0) {
-        output.WriteInt32(1, fieldNames[36], SingleInt32);
+        output.WriteInt32(1, SingleInt32);
       }
       if (SingleInt64 != 0L) {
-        output.WriteInt64(2, fieldNames[37], SingleInt64);
+        output.WriteInt64(2, SingleInt64);
       }
       if (SingleUint32 != 0) {
-        output.WriteUInt32(3, fieldNames[46], SingleUint32);
+        output.WriteUInt32(3, SingleUint32);
       }
       if (SingleUint64 != 0UL) {
-        output.WriteUInt64(4, fieldNames[47], SingleUint64);
+        output.WriteUInt64(4, SingleUint64);
       }
       if (SingleSint32 != 0) {
-        output.WriteSInt32(5, fieldNames[43], SingleSint32);
+        output.WriteSInt32(5, SingleSint32);
       }
       if (SingleSint64 != 0L) {
-        output.WriteSInt64(6, fieldNames[44], SingleSint64);
+        output.WriteSInt64(6, SingleSint64);
       }
       if (SingleFixed32 != 0) {
-        output.WriteFixed32(7, fieldNames[29], SingleFixed32);
+        output.WriteFixed32(7, SingleFixed32);
       }
       if (SingleFixed64 != 0UL) {
-        output.WriteFixed64(8, fieldNames[30], SingleFixed64);
+        output.WriteFixed64(8, SingleFixed64);
       }
       if (SingleSfixed32 != 0) {
-        output.WriteSFixed32(9, fieldNames[41], SingleSfixed32);
+        output.WriteSFixed32(9, SingleSfixed32);
       }
       if (SingleSfixed64 != 0L) {
-        output.WriteSFixed64(10, fieldNames[42], SingleSfixed64);
+        output.WriteSFixed64(10, SingleSfixed64);
       }
       if (SingleFloat != 0F) {
-        output.WriteFloat(11, fieldNames[31], SingleFloat);
+        output.WriteFloat(11, SingleFloat);
       }
       if (SingleDouble != 0D) {
-        output.WriteDouble(12, fieldNames[28], SingleDouble);
+        output.WriteDouble(12, SingleDouble);
       }
       if (SingleBool != false) {
-        output.WriteBool(13, fieldNames[26], SingleBool);
+        output.WriteBool(13, SingleBool);
       }
       if (SingleString != "") {
-        output.WriteString(14, fieldNames[45], SingleString);
+        output.WriteString(14, SingleString);
       }
       if (SingleBytes != pb::ByteString.Empty) {
-        output.WriteBytes(15, fieldNames[27], SingleBytes);
+        output.WriteBytes(15, SingleBytes);
       }
       if (singleNestedMessage_ != null) {
-        output.WriteMessage(18, fieldNames[39], SingleNestedMessage);
+        output.WriteMessage(18, SingleNestedMessage);
       }
       if (singleForeignMessage_ != null) {
-        output.WriteMessage(19, fieldNames[33], SingleForeignMessage);
+        output.WriteMessage(19, SingleForeignMessage);
       }
       if (singleImportMessage_ != null) {
-        output.WriteMessage(20, fieldNames[35], SingleImportMessage);
+        output.WriteMessage(20, SingleImportMessage);
       }
       if (SingleNestedEnum != global::Google.Protobuf.TestProtos.TestAllTypes.Types.NestedEnum.NESTED_ENUM_UNSPECIFIED) {
-        output.WriteEnum(21, fieldNames[38], (int) SingleNestedEnum);
+        output.WriteEnum(21, (int) SingleNestedEnum);
       }
       if (SingleForeignEnum != global::Google.Protobuf.TestProtos.ForeignEnum.FOREIGN_UNSPECIFIED) {
-        output.WriteEnum(22, fieldNames[32], (int) SingleForeignEnum);
+        output.WriteEnum(22, (int) SingleForeignEnum);
       }
       if (SingleImportEnum != global::Google.Protobuf.TestProtos.ImportEnum.IMPORT_ENUM_UNSPECIFIED) {
-        output.WriteEnum(23, fieldNames[34], (int) SingleImportEnum);
+        output.WriteEnum(23, (int) SingleImportEnum);
       }
       if (singlePublicImportMessage_ != null) {
-        output.WriteMessage(26, fieldNames[40], SinglePublicImportMessage);
+        output.WriteMessage(26, SinglePublicImportMessage);
       }
-      output.WritePackedInt32Array(31, fieldNames[14], repeatedInt32_);
-      output.WritePackedInt64Array(32, fieldNames[15], repeatedInt64_);
-      output.WritePackedUInt32Array(33, fieldNames[24], repeatedUint32_);
-      output.WritePackedUInt64Array(34, fieldNames[25], repeatedUint64_);
-      output.WritePackedSInt32Array(35, fieldNames[21], repeatedSint32_);
-      output.WritePackedSInt64Array(36, fieldNames[22], repeatedSint64_);
-      output.WritePackedFixed32Array(37, fieldNames[7], repeatedFixed32_);
-      output.WritePackedFixed64Array(38, fieldNames[8], repeatedFixed64_);
-      output.WritePackedSFixed32Array(39, fieldNames[19], repeatedSfixed32_);
-      output.WritePackedSFixed64Array(40, fieldNames[20], repeatedSfixed64_);
-      output.WritePackedFloatArray(41, fieldNames[9], repeatedFloat_);
-      output.WritePackedDoubleArray(42, fieldNames[6], repeatedDouble_);
-      output.WritePackedBoolArray(43, fieldNames[4], repeatedBool_);
-      output.WriteStringArray(44, fieldNames[23], repeatedString_);
-      output.WriteBytesArray(45, fieldNames[5], repeatedBytes_);
-      output.WriteMessageArray(48, fieldNames[17], repeatedNestedMessage_);
-      output.WriteMessageArray(49, fieldNames[11], repeatedForeignMessage_);
-      output.WriteMessageArray(50, fieldNames[13], repeatedImportMessage_);
-      output.WritePackedEnumArray(51, fieldNames[16], repeatedNestedEnum_);
-      output.WritePackedEnumArray(52, fieldNames[10], repeatedForeignEnum_);
-      output.WritePackedEnumArray(53, fieldNames[12], repeatedImportEnum_);
-      output.WriteMessageArray(54, fieldNames[18], repeatedPublicImportMessage_);
+      output.WritePackedInt32Array(31, repeatedInt32_);
+      output.WritePackedInt64Array(32, repeatedInt64_);
+      output.WritePackedUInt32Array(33, repeatedUint32_);
+      output.WritePackedUInt64Array(34, repeatedUint64_);
+      output.WritePackedSInt32Array(35, repeatedSint32_);
+      output.WritePackedSInt64Array(36, repeatedSint64_);
+      output.WritePackedFixed32Array(37, repeatedFixed32_);
+      output.WritePackedFixed64Array(38, repeatedFixed64_);
+      output.WritePackedSFixed32Array(39, repeatedSfixed32_);
+      output.WritePackedSFixed64Array(40, repeatedSfixed64_);
+      output.WritePackedFloatArray(41, repeatedFloat_);
+      output.WritePackedDoubleArray(42, repeatedDouble_);
+      output.WritePackedBoolArray(43, repeatedBool_);
+      output.WriteStringArray(44, repeatedString_);
+      output.WriteBytesArray(45, repeatedBytes_);
+      output.WriteMessageArray(48, repeatedNestedMessage_);
+      output.WriteMessageArray(49, repeatedForeignMessage_);
+      output.WriteMessageArray(50, repeatedImportMessage_);
+      output.WritePackedEnumArray(51, repeatedNestedEnum_);
+      output.WritePackedEnumArray(52, repeatedForeignEnum_);
+      output.WritePackedEnumArray(53, repeatedImportEnum_);
+      output.WriteMessageArray(54, repeatedPublicImportMessage_);
       if (oneofFieldCase_ == OneofFieldOneofCase.OneofUint32) {
-        output.WriteUInt32(111, fieldNames[3], OneofUint32);
+        output.WriteUInt32(111, OneofUint32);
       }
       if (oneofFieldCase_ == OneofFieldOneofCase.OneofNestedMessage) {
-        output.WriteMessage(112, fieldNames[1], OneofNestedMessage);
+        output.WriteMessage(112, OneofNestedMessage);
       }
       if (oneofFieldCase_ == OneofFieldOneofCase.OneofString) {
-        output.WriteString(113, fieldNames[2], OneofString);
+        output.WriteString(113, OneofString);
       }
       if (oneofFieldCase_ == OneofFieldOneofCase.OneofBytes) {
-        output.WriteBytes(114, fieldNames[0], OneofBytes);
+        output.WriteBytes(114, OneofBytes);
       }
     }
 
@@ -1372,16 +1371,9 @@
 
     }
 
-    public void MergeFrom(pb::ICodedInputStream input) {
+    public void MergeFrom(pb::CodedInputStream input) {
       uint tag;
-      string fieldName;
-      while (input.ReadTag(out tag, out fieldName)) {
-        if (tag == 0 && fieldName != null) {
-          int fieldOrdinal = global::System.Array.BinarySearch(_fieldNames, fieldName, global::System.StringComparer.Ordinal);
-          if (fieldOrdinal >= 0) {
-            tag = _fieldTags[fieldOrdinal];
-          }
-        }
+      while (input.ReadTag(out tag)) {
         switch(tag) {
           case 0:
             throw pb::InvalidProtocolBufferException.InvalidTag();
@@ -1391,63 +1383,63 @@
             }
             break;
           case 8: {
-            input.ReadInt32(ref singleInt32_);
+            singleInt32_ = input.ReadInt32();
             break;
           }
           case 16: {
-            input.ReadInt64(ref singleInt64_);
+            singleInt64_ = input.ReadInt64();
             break;
           }
           case 24: {
-            input.ReadUInt32(ref singleUint32_);
+            singleUint32_ = input.ReadUInt32();
             break;
           }
           case 32: {
-            input.ReadUInt64(ref singleUint64_);
+            singleUint64_ = input.ReadUInt64();
             break;
           }
           case 40: {
-            input.ReadSInt32(ref singleSint32_);
+            singleSint32_ = input.ReadSInt32();
             break;
           }
           case 48: {
-            input.ReadSInt64(ref singleSint64_);
+            singleSint64_ = input.ReadSInt64();
             break;
           }
           case 61: {
-            input.ReadFixed32(ref singleFixed32_);
+            singleFixed32_ = input.ReadFixed32();
             break;
           }
           case 65: {
-            input.ReadFixed64(ref singleFixed64_);
+            singleFixed64_ = input.ReadFixed64();
             break;
           }
           case 77: {
-            input.ReadSFixed32(ref singleSfixed32_);
+            singleSfixed32_ = input.ReadSFixed32();
             break;
           }
           case 81: {
-            input.ReadSFixed64(ref singleSfixed64_);
+            singleSfixed64_ = input.ReadSFixed64();
             break;
           }
           case 93: {
-            input.ReadFloat(ref singleFloat_);
+            singleFloat_ = input.ReadFloat();
             break;
           }
           case 97: {
-            input.ReadDouble(ref singleDouble_);
+            singleDouble_ = input.ReadDouble();
             break;
           }
           case 104: {
-            input.ReadBool(ref singleBool_);
+            singleBool_ = input.ReadBool();
             break;
           }
           case 114: {
-            input.ReadString(ref singleString_);
+            singleString_ = input.ReadString();
             break;
           }
           case 122: {
-            input.ReadBytes(ref singleBytes_);
+            singleBytes_ = input.ReadBytes();
             break;
           }
           case 146: {
@@ -1472,19 +1464,16 @@
             break;
           }
           case 168: {
-            int tmp = 0;
-            input.ReadEnum(ref tmp);
-            singleNestedEnum_ = (global::Google.Protobuf.TestProtos.TestAllTypes.Types.NestedEnum) tmp;break;
+            singleNestedEnum_ = (global::Google.Protobuf.TestProtos.TestAllTypes.Types.NestedEnum) input.ReadEnum();
+            break;
           }
           case 176: {
-            int tmp = 0;
-            input.ReadEnum(ref tmp);
-            singleForeignEnum_ = (global::Google.Protobuf.TestProtos.ForeignEnum) tmp;break;
+            singleForeignEnum_ = (global::Google.Protobuf.TestProtos.ForeignEnum) input.ReadEnum();
+            break;
           }
           case 184: {
-            int tmp = 0;
-            input.ReadEnum(ref tmp);
-            singleImportEnum_ = (global::Google.Protobuf.TestProtos.ImportEnum) tmp;break;
+            singleImportEnum_ = (global::Google.Protobuf.TestProtos.ImportEnum) input.ReadEnum();
+            break;
           }
           case 210: {
             if (singlePublicImportMessage_ == null) {
@@ -1495,114 +1484,111 @@
           }
           case 250:
           case 248: {
-            input.ReadInt32Array(tag, fieldName, repeatedInt32_);
+            input.ReadInt32Array(tag, repeatedInt32_);
             break;
           }
           case 258:
           case 256: {
-            input.ReadInt64Array(tag, fieldName, repeatedInt64_);
+            input.ReadInt64Array(tag, repeatedInt64_);
             break;
           }
           case 266:
           case 264: {
-            input.ReadUInt32Array(tag, fieldName, repeatedUint32_);
+            input.ReadUInt32Array(tag, repeatedUint32_);
             break;
           }
           case 274:
           case 272: {
-            input.ReadUInt64Array(tag, fieldName, repeatedUint64_);
+            input.ReadUInt64Array(tag, repeatedUint64_);
             break;
           }
           case 282:
           case 280: {
-            input.ReadSInt32Array(tag, fieldName, repeatedSint32_);
+            input.ReadSInt32Array(tag, repeatedSint32_);
             break;
           }
           case 290:
           case 288: {
-            input.ReadSInt64Array(tag, fieldName, repeatedSint64_);
+            input.ReadSInt64Array(tag, repeatedSint64_);
             break;
           }
           case 298:
           case 301: {
-            input.ReadFixed32Array(tag, fieldName, repeatedFixed32_);
+            input.ReadFixed32Array(tag, repeatedFixed32_);
             break;
           }
           case 306:
           case 305: {
-            input.ReadFixed64Array(tag, fieldName, repeatedFixed64_);
+            input.ReadFixed64Array(tag, repeatedFixed64_);
             break;
           }
           case 314:
           case 317: {
-            input.ReadSFixed32Array(tag, fieldName, repeatedSfixed32_);
+            input.ReadSFixed32Array(tag, repeatedSfixed32_);
             break;
           }
           case 322:
           case 321: {
-            input.ReadSFixed64Array(tag, fieldName, repeatedSfixed64_);
+            input.ReadSFixed64Array(tag, repeatedSfixed64_);
             break;
           }
           case 330:
           case 333: {
-            input.ReadFloatArray(tag, fieldName, repeatedFloat_);
+            input.ReadFloatArray(tag, repeatedFloat_);
             break;
           }
           case 338:
           case 337: {
-            input.ReadDoubleArray(tag, fieldName, repeatedDouble_);
+            input.ReadDoubleArray(tag, repeatedDouble_);
             break;
           }
           case 346:
           case 344: {
-            input.ReadBoolArray(tag, fieldName, repeatedBool_);
+            input.ReadBoolArray(tag, repeatedBool_);
             break;
           }
           case 354: {
-            input.ReadStringArray(tag, fieldName, repeatedString_);
+            input.ReadStringArray(tag, repeatedString_);
             break;
           }
           case 362: {
-            input.ReadBytesArray(tag, fieldName, repeatedBytes_);
+            input.ReadBytesArray(tag, repeatedBytes_);
             break;
           }
           case 386: {
-            input.ReadMessageArray(tag, fieldName, repeatedNestedMessage_, global::Google.Protobuf.TestProtos.TestAllTypes.Types.NestedMessage.Parser);
+            input.ReadMessageArray(tag, repeatedNestedMessage_, global::Google.Protobuf.TestProtos.TestAllTypes.Types.NestedMessage.Parser);
             break;
           }
           case 394: {
-            input.ReadMessageArray(tag, fieldName, repeatedForeignMessage_, global::Google.Protobuf.TestProtos.ForeignMessage.Parser);
+            input.ReadMessageArray(tag, repeatedForeignMessage_, global::Google.Protobuf.TestProtos.ForeignMessage.Parser);
             break;
           }
           case 402: {
-            input.ReadMessageArray(tag, fieldName, repeatedImportMessage_, global::Google.Protobuf.TestProtos.ImportMessage.Parser);
+            input.ReadMessageArray(tag, repeatedImportMessage_, global::Google.Protobuf.TestProtos.ImportMessage.Parser);
             break;
           }
           case 410:
           case 408: {
-            input.ReadEnumArray<global::Google.Protobuf.TestProtos.TestAllTypes.Types.NestedEnum>(tag, fieldName, repeatedNestedEnum_);
+            input.ReadEnumArray<global::Google.Protobuf.TestProtos.TestAllTypes.Types.NestedEnum>(tag, repeatedNestedEnum_);
             break;
           }
           case 418:
           case 416: {
-            input.ReadEnumArray<global::Google.Protobuf.TestProtos.ForeignEnum>(tag, fieldName, repeatedForeignEnum_);
+            input.ReadEnumArray<global::Google.Protobuf.TestProtos.ForeignEnum>(tag, repeatedForeignEnum_);
             break;
           }
           case 426:
           case 424: {
-            input.ReadEnumArray<global::Google.Protobuf.TestProtos.ImportEnum>(tag, fieldName, repeatedImportEnum_);
+            input.ReadEnumArray<global::Google.Protobuf.TestProtos.ImportEnum>(tag, repeatedImportEnum_);
             break;
           }
           case 434: {
-            input.ReadMessageArray(tag, fieldName, repeatedPublicImportMessage_, global::Google.Protobuf.TestProtos.PublicImportMessage.Parser);
+            input.ReadMessageArray(tag, repeatedPublicImportMessage_, global::Google.Protobuf.TestProtos.PublicImportMessage.Parser);
             break;
           }
           case 888: {
-            uint value = 0;
-            if (input.ReadUInt32(ref value)) {
-              oneofField_ = value;
-              oneofFieldCase_ = OneofFieldOneofCase.OneofUint32;
-            }
+            oneofField_ = input.ReadUInt32()
+            ;oneofFieldCase_ = OneofFieldOneofCase.OneofUint32;
             break;
           }
           case 898: {
@@ -1615,19 +1601,13 @@
             break;
           }
           case 906: {
-            string value = "";
-            if (input.ReadString(ref value)) {
-              oneofField_ = value;
-              oneofFieldCase_ = OneofFieldOneofCase.OneofString;
-            }
+            oneofField_ = input.ReadString()
+            ;oneofFieldCase_ = OneofFieldOneofCase.OneofString;
             break;
           }
           case 914: {
-            pb::ByteString value = pb::ByteString.Empty;
-            if (input.ReadBytes(ref value)) {
-              oneofField_ = value;
-              oneofFieldCase_ = OneofFieldOneofCase.OneofBytes;
-            }
+            oneofField_ = input.ReadBytes()
+            ;oneofFieldCase_ = OneofFieldOneofCase.OneofBytes;
             break;
           }
         }
@@ -1693,10 +1673,9 @@
           return hash;
         }
 
-        public void WriteTo(pb::ICodedOutputStream output) {
-          string[] fieldNames = _fieldNames;
+        public void WriteTo(pb::CodedOutputStream output) {
           if (Bb != 0) {
-            output.WriteInt32(1, fieldNames[0], Bb);
+            output.WriteInt32(1, Bb);
           }
         }
 
@@ -1716,16 +1695,9 @@
           }
         }
 
-        public void MergeFrom(pb::ICodedInputStream input) {
+        public void MergeFrom(pb::CodedInputStream input) {
           uint tag;
-          string fieldName;
-          while (input.ReadTag(out tag, out fieldName)) {
-            if (tag == 0 && fieldName != null) {
-              int fieldOrdinal = global::System.Array.BinarySearch(_fieldNames, fieldName, global::System.StringComparer.Ordinal);
-              if (fieldOrdinal >= 0) {
-                tag = _fieldTags[fieldOrdinal];
-              }
-            }
+          while (input.ReadTag(out tag)) {
             switch(tag) {
               case 0:
                 throw pb::InvalidProtocolBufferException.InvalidTag();
@@ -1735,7 +1707,7 @@
                 }
                 break;
               case 8: {
-                input.ReadInt32(ref bb_);
+                bb_ = input.ReadInt32();
                 break;
               }
             }
@@ -1811,15 +1783,14 @@
       return hash;
     }
 
-    public void WriteTo(pb::ICodedOutputStream output) {
-      string[] fieldNames = _fieldNames;
+    public void WriteTo(pb::CodedOutputStream output) {
       if (child_ != null) {
-        output.WriteMessage(1, fieldNames[0], Child);
+        output.WriteMessage(1, Child);
       }
       if (payload_ != null) {
-        output.WriteMessage(2, fieldNames[1], Payload);
+        output.WriteMessage(2, Payload);
       }
-      output.WriteMessageArray(3, fieldNames[2], repeatedChild_);
+      output.WriteMessageArray(3, repeatedChild_);
     }
 
     public int CalculateSize() {
@@ -1854,16 +1825,9 @@
       repeatedChild_.Add(other.repeatedChild_);
     }
 
-    public void MergeFrom(pb::ICodedInputStream input) {
+    public void MergeFrom(pb::CodedInputStream input) {
       uint tag;
-      string fieldName;
-      while (input.ReadTag(out tag, out fieldName)) {
-        if (tag == 0 && fieldName != null) {
-          int fieldOrdinal = global::System.Array.BinarySearch(_fieldNames, fieldName, global::System.StringComparer.Ordinal);
-          if (fieldOrdinal >= 0) {
-            tag = _fieldTags[fieldOrdinal];
-          }
-        }
+      while (input.ReadTag(out tag)) {
         switch(tag) {
           case 0:
             throw pb::InvalidProtocolBufferException.InvalidTag();
@@ -1887,7 +1851,7 @@
             break;
           }
           case 26: {
-            input.ReadMessageArray(tag, fieldName, repeatedChild_, global::Google.Protobuf.TestProtos.NestedTestAllTypes.Parser);
+            input.ReadMessageArray(tag, repeatedChild_, global::Google.Protobuf.TestProtos.NestedTestAllTypes.Parser);
             break;
           }
         }
@@ -1945,10 +1909,9 @@
       return hash;
     }
 
-    public void WriteTo(pb::ICodedOutputStream output) {
-      string[] fieldNames = _fieldNames;
+    public void WriteTo(pb::CodedOutputStream output) {
       if (DeprecatedInt32 != 0) {
-        output.WriteInt32(1, fieldNames[0], DeprecatedInt32);
+        output.WriteInt32(1, DeprecatedInt32);
       }
     }
 
@@ -1968,16 +1931,9 @@
       }
     }
 
-    public void MergeFrom(pb::ICodedInputStream input) {
+    public void MergeFrom(pb::CodedInputStream input) {
       uint tag;
-      string fieldName;
-      while (input.ReadTag(out tag, out fieldName)) {
-        if (tag == 0 && fieldName != null) {
-          int fieldOrdinal = global::System.Array.BinarySearch(_fieldNames, fieldName, global::System.StringComparer.Ordinal);
-          if (fieldOrdinal >= 0) {
-            tag = _fieldTags[fieldOrdinal];
-          }
-        }
+      while (input.ReadTag(out tag)) {
         switch(tag) {
           case 0:
             throw pb::InvalidProtocolBufferException.InvalidTag();
@@ -1987,7 +1943,7 @@
             }
             break;
           case 8: {
-            input.ReadInt32(ref deprecatedInt32_);
+            deprecatedInt32_ = input.ReadInt32();
             break;
           }
         }
@@ -2044,10 +2000,9 @@
       return hash;
     }
 
-    public void WriteTo(pb::ICodedOutputStream output) {
-      string[] fieldNames = _fieldNames;
+    public void WriteTo(pb::CodedOutputStream output) {
       if (C != 0) {
-        output.WriteInt32(1, fieldNames[0], C);
+        output.WriteInt32(1, C);
       }
     }
 
@@ -2067,16 +2022,9 @@
       }
     }
 
-    public void MergeFrom(pb::ICodedInputStream input) {
+    public void MergeFrom(pb::CodedInputStream input) {
       uint tag;
-      string fieldName;
-      while (input.ReadTag(out tag, out fieldName)) {
-        if (tag == 0 && fieldName != null) {
-          int fieldOrdinal = global::System.Array.BinarySearch(_fieldNames, fieldName, global::System.StringComparer.Ordinal);
-          if (fieldOrdinal >= 0) {
-            tag = _fieldTags[fieldOrdinal];
-          }
-        }
+      while (input.ReadTag(out tag)) {
         switch(tag) {
           case 0:
             throw pb::InvalidProtocolBufferException.InvalidTag();
@@ -2086,7 +2034,7 @@
             }
             break;
           case 8: {
-            input.ReadInt32(ref c_);
+            c_ = input.ReadInt32();
             break;
           }
         }
@@ -2133,8 +2081,7 @@
       return hash;
     }
 
-    public void WriteTo(pb::ICodedOutputStream output) {
-      string[] fieldNames = _fieldNames;
+    public void WriteTo(pb::CodedOutputStream output) {
     }
 
     public int CalculateSize() {
@@ -2147,16 +2094,9 @@
       }
     }
 
-    public void MergeFrom(pb::ICodedInputStream input) {
+    public void MergeFrom(pb::CodedInputStream input) {
       uint tag;
-      string fieldName;
-      while (input.ReadTag(out tag, out fieldName)) {
-        if (tag == 0 && fieldName != null) {
-          int fieldOrdinal = global::System.Array.BinarySearch(_fieldNames, fieldName, global::System.StringComparer.Ordinal);
-          if (fieldOrdinal >= 0) {
-            tag = _fieldTags[fieldOrdinal];
-          }
-        }
+      while (input.ReadTag(out tag)) {
         switch(tag) {
           case 0:
             throw pb::InvalidProtocolBufferException.InvalidTag();
@@ -2217,10 +2157,9 @@
       return hash;
     }
 
-    public void WriteTo(pb::ICodedOutputStream output) {
-      string[] fieldNames = _fieldNames;
+    public void WriteTo(pb::CodedOutputStream output) {
       if (foreignNested_ != null) {
-        output.WriteMessage(1, fieldNames[0], ForeignNested);
+        output.WriteMessage(1, ForeignNested);
       }
     }
 
@@ -2243,16 +2182,9 @@
       }
     }
 
-    public void MergeFrom(pb::ICodedInputStream input) {
+    public void MergeFrom(pb::CodedInputStream input) {
       uint tag;
-      string fieldName;
-      while (input.ReadTag(out tag, out fieldName)) {
-        if (tag == 0 && fieldName != null) {
-          int fieldOrdinal = global::System.Array.BinarySearch(_fieldNames, fieldName, global::System.StringComparer.Ordinal);
-          if (fieldOrdinal >= 0) {
-            tag = _fieldTags[fieldOrdinal];
-          }
-        }
+      while (input.ReadTag(out tag)) {
         switch(tag) {
           case 0:
             throw pb::InvalidProtocolBufferException.InvalidTag();
@@ -2332,13 +2264,12 @@
       return hash;
     }
 
-    public void WriteTo(pb::ICodedOutputStream output) {
-      string[] fieldNames = _fieldNames;
+    public void WriteTo(pb::CodedOutputStream output) {
       if (A != 0) {
-        output.WriteInt32(1, fieldNames[0], A);
+        output.WriteInt32(1, A);
       }
       if (Bb != 0) {
-        output.WriteInt32(268435455, fieldNames[1], Bb);
+        output.WriteInt32(268435455, Bb);
       }
     }
 
@@ -2364,16 +2295,9 @@
       }
     }
 
-    public void MergeFrom(pb::ICodedInputStream input) {
+    public void MergeFrom(pb::CodedInputStream input) {
       uint tag;
-      string fieldName;
-      while (input.ReadTag(out tag, out fieldName)) {
-        if (tag == 0 && fieldName != null) {
-          int fieldOrdinal = global::System.Array.BinarySearch(_fieldNames, fieldName, global::System.StringComparer.Ordinal);
-          if (fieldOrdinal >= 0) {
-            tag = _fieldTags[fieldOrdinal];
-          }
-        }
+      while (input.ReadTag(out tag)) {
         switch(tag) {
           case 0:
             throw pb::InvalidProtocolBufferException.InvalidTag();
@@ -2383,11 +2307,11 @@
             }
             break;
           case 8: {
-            input.ReadInt32(ref a_);
+            a_ = input.ReadInt32();
             break;
           }
           case 2147483640: {
-            input.ReadInt32(ref bb_);
+            bb_ = input.ReadInt32();
             break;
           }
         }
@@ -2452,13 +2376,12 @@
       return hash;
     }
 
-    public void WriteTo(pb::ICodedOutputStream output) {
-      string[] fieldNames = _fieldNames;
+    public void WriteTo(pb::CodedOutputStream output) {
       if (a_ != null) {
-        output.WriteMessage(1, fieldNames[0], A);
+        output.WriteMessage(1, A);
       }
       if (I != 0) {
-        output.WriteInt32(2, fieldNames[1], I);
+        output.WriteInt32(2, I);
       }
     }
 
@@ -2487,16 +2410,9 @@
       }
     }
 
-    public void MergeFrom(pb::ICodedInputStream input) {
+    public void MergeFrom(pb::CodedInputStream input) {
       uint tag;
-      string fieldName;
-      while (input.ReadTag(out tag, out fieldName)) {
-        if (tag == 0 && fieldName != null) {
-          int fieldOrdinal = global::System.Array.BinarySearch(_fieldNames, fieldName, global::System.StringComparer.Ordinal);
-          if (fieldOrdinal >= 0) {
-            tag = _fieldTags[fieldOrdinal];
-          }
-        }
+      while (input.ReadTag(out tag)) {
         switch(tag) {
           case 0:
             throw pb::InvalidProtocolBufferException.InvalidTag();
@@ -2513,7 +2429,7 @@
             break;
           }
           case 16: {
-            input.ReadInt32(ref i_);
+            i_ = input.ReadInt32();
             break;
           }
         }
@@ -2568,10 +2484,9 @@
       return hash;
     }
 
-    public void WriteTo(pb::ICodedOutputStream output) {
-      string[] fieldNames = _fieldNames;
+    public void WriteTo(pb::CodedOutputStream output) {
       if (bb_ != null) {
-        output.WriteMessage(1, fieldNames[0], Bb);
+        output.WriteMessage(1, Bb);
       }
     }
 
@@ -2594,16 +2509,9 @@
       }
     }
 
-    public void MergeFrom(pb::ICodedInputStream input) {
+    public void MergeFrom(pb::CodedInputStream input) {
       uint tag;
-      string fieldName;
-      while (input.ReadTag(out tag, out fieldName)) {
-        if (tag == 0 && fieldName != null) {
-          int fieldOrdinal = global::System.Array.BinarySearch(_fieldNames, fieldName, global::System.StringComparer.Ordinal);
-          if (fieldOrdinal >= 0) {
-            tag = _fieldTags[fieldOrdinal];
-          }
-        }
+      while (input.ReadTag(out tag)) {
         switch(tag) {
           case 0:
             throw pb::InvalidProtocolBufferException.InvalidTag();
@@ -2681,13 +2589,12 @@
       return hash;
     }
 
-    public void WriteTo(pb::ICodedOutputStream output) {
-      string[] fieldNames = _fieldNames;
+    public void WriteTo(pb::CodedOutputStream output) {
       if (a_ != null) {
-        output.WriteMessage(1, fieldNames[0], A);
+        output.WriteMessage(1, A);
       }
       if (OptionalInt32 != 0) {
-        output.WriteInt32(2, fieldNames[1], OptionalInt32);
+        output.WriteInt32(2, OptionalInt32);
       }
     }
 
@@ -2716,16 +2623,9 @@
       }
     }
 
-    public void MergeFrom(pb::ICodedInputStream input) {
+    public void MergeFrom(pb::CodedInputStream input) {
       uint tag;
-      string fieldName;
-      while (input.ReadTag(out tag, out fieldName)) {
-        if (tag == 0 && fieldName != null) {
-          int fieldOrdinal = global::System.Array.BinarySearch(_fieldNames, fieldName, global::System.StringComparer.Ordinal);
-          if (fieldOrdinal >= 0) {
-            tag = _fieldTags[fieldOrdinal];
-          }
-        }
+      while (input.ReadTag(out tag)) {
         switch(tag) {
           case 0:
             throw pb::InvalidProtocolBufferException.InvalidTag();
@@ -2742,7 +2642,7 @@
             break;
           }
           case 16: {
-            input.ReadInt32(ref optionalInt32_);
+            optionalInt32_ = input.ReadInt32();
             break;
           }
         }
@@ -2859,24 +2759,23 @@
       return hash;
     }
 
-    public void WriteTo(pb::ICodedOutputStream output) {
-      string[] fieldNames = _fieldNames;
+    public void WriteTo(pb::CodedOutputStream output) {
       if (PrimitiveField != 0) {
-        output.WriteInt32(1, fieldNames[2], PrimitiveField);
+        output.WriteInt32(1, PrimitiveField);
       }
       if (StringField != "") {
-        output.WriteString(2, fieldNames[7], StringField);
+        output.WriteString(2, StringField);
       }
       if (EnumField != global::Google.Protobuf.TestProtos.ForeignEnum.FOREIGN_UNSPECIFIED) {
-        output.WriteEnum(3, fieldNames[0], (int) EnumField);
+        output.WriteEnum(3, (int) EnumField);
       }
       if (messageField_ != null) {
-        output.WriteMessage(4, fieldNames[1], MessageField);
+        output.WriteMessage(4, MessageField);
       }
-      output.WritePackedInt32Array(7, fieldNames[5], repeatedPrimitiveField_);
-      output.WriteStringArray(8, fieldNames[6], repeatedStringField_);
-      output.WritePackedEnumArray(9, fieldNames[3], repeatedEnumField_);
-      output.WriteMessageArray(10, fieldNames[4], repeatedMessageField_);
+      output.WritePackedInt32Array(7, repeatedPrimitiveField_);
+      output.WriteStringArray(8, repeatedStringField_);
+      output.WritePackedEnumArray(9, repeatedEnumField_);
+      output.WriteMessageArray(10, repeatedMessageField_);
     }
 
     public int CalculateSize() {
@@ -2952,16 +2851,9 @@
       repeatedMessageField_.Add(other.repeatedMessageField_);
     }
 
-    public void MergeFrom(pb::ICodedInputStream input) {
+    public void MergeFrom(pb::CodedInputStream input) {
       uint tag;
-      string fieldName;
-      while (input.ReadTag(out tag, out fieldName)) {
-        if (tag == 0 && fieldName != null) {
-          int fieldOrdinal = global::System.Array.BinarySearch(_fieldNames, fieldName, global::System.StringComparer.Ordinal);
-          if (fieldOrdinal >= 0) {
-            tag = _fieldTags[fieldOrdinal];
-          }
-        }
+      while (input.ReadTag(out tag)) {
         switch(tag) {
           case 0:
             throw pb::InvalidProtocolBufferException.InvalidTag();
@@ -2971,17 +2863,16 @@
             }
             break;
           case 8: {
-            input.ReadInt32(ref primitiveField_);
+            primitiveField_ = input.ReadInt32();
             break;
           }
           case 18: {
-            input.ReadString(ref stringField_);
+            stringField_ = input.ReadString();
             break;
           }
           case 24: {
-            int tmp = 0;
-            input.ReadEnum(ref tmp);
-            enumField_ = (global::Google.Protobuf.TestProtos.ForeignEnum) tmp;break;
+            enumField_ = (global::Google.Protobuf.TestProtos.ForeignEnum) input.ReadEnum();
+            break;
           }
           case 34: {
             if (messageField_ == null) {
@@ -2992,20 +2883,20 @@
           }
           case 58:
           case 56: {
-            input.ReadInt32Array(tag, fieldName, repeatedPrimitiveField_);
+            input.ReadInt32Array(tag, repeatedPrimitiveField_);
             break;
           }
           case 66: {
-            input.ReadStringArray(tag, fieldName, repeatedStringField_);
+            input.ReadStringArray(tag, repeatedStringField_);
             break;
           }
           case 74:
           case 72: {
-            input.ReadEnumArray<global::Google.Protobuf.TestProtos.ForeignEnum>(tag, fieldName, repeatedEnumField_);
+            input.ReadEnumArray<global::Google.Protobuf.TestProtos.ForeignEnum>(tag, repeatedEnumField_);
             break;
           }
           case 82: {
-            input.ReadMessageArray(tag, fieldName, repeatedMessageField_, global::Google.Protobuf.TestProtos.ForeignMessage.Parser);
+            input.ReadMessageArray(tag, repeatedMessageField_, global::Google.Protobuf.TestProtos.ForeignMessage.Parser);
             break;
           }
         }
@@ -3090,19 +2981,18 @@
       return hash;
     }
 
-    public void WriteTo(pb::ICodedOutputStream output) {
-      string[] fieldNames = _fieldNames;
+    public void WriteTo(pb::CodedOutputStream output) {
       if (MyInt != 0L) {
-        output.WriteInt64(1, fieldNames[1], MyInt);
+        output.WriteInt64(1, MyInt);
       }
       if (MyString != "") {
-        output.WriteString(11, fieldNames[2], MyString);
+        output.WriteString(11, MyString);
       }
       if (MyFloat != 0F) {
-        output.WriteFloat(101, fieldNames[0], MyFloat);
+        output.WriteFloat(101, MyFloat);
       }
       if (singleNestedMessage_ != null) {
-        output.WriteMessage(200, fieldNames[3], SingleNestedMessage);
+        output.WriteMessage(200, SingleNestedMessage);
       }
     }
 
@@ -3143,16 +3033,9 @@
       }
     }
 
-    public void MergeFrom(pb::ICodedInputStream input) {
+    public void MergeFrom(pb::CodedInputStream input) {
       uint tag;
-      string fieldName;
-      while (input.ReadTag(out tag, out fieldName)) {
-        if (tag == 0 && fieldName != null) {
-          int fieldOrdinal = global::System.Array.BinarySearch(_fieldNames, fieldName, global::System.StringComparer.Ordinal);
-          if (fieldOrdinal >= 0) {
-            tag = _fieldTags[fieldOrdinal];
-          }
-        }
+      while (input.ReadTag(out tag)) {
         switch(tag) {
           case 0:
             throw pb::InvalidProtocolBufferException.InvalidTag();
@@ -3162,15 +3045,15 @@
             }
             break;
           case 8: {
-            input.ReadInt64(ref myInt_);
+            myInt_ = input.ReadInt64();
             break;
           }
           case 90: {
-            input.ReadString(ref myString_);
+            myString_ = input.ReadString();
             break;
           }
           case 813: {
-            input.ReadFloat(ref myFloat_);
+            myFloat_ = input.ReadFloat();
             break;
           }
           case 1602: {
@@ -3245,13 +3128,12 @@
           return hash;
         }
 
-        public void WriteTo(pb::ICodedOutputStream output) {
-          string[] fieldNames = _fieldNames;
+        public void WriteTo(pb::CodedOutputStream output) {
           if (Bb != 0) {
-            output.WriteInt32(1, fieldNames[0], Bb);
+            output.WriteInt32(1, Bb);
           }
           if (Oo != 0L) {
-            output.WriteInt64(2, fieldNames[1], Oo);
+            output.WriteInt64(2, Oo);
           }
         }
 
@@ -3277,16 +3159,9 @@
           }
         }
 
-        public void MergeFrom(pb::ICodedInputStream input) {
+        public void MergeFrom(pb::CodedInputStream input) {
           uint tag;
-          string fieldName;
-          while (input.ReadTag(out tag, out fieldName)) {
-            if (tag == 0 && fieldName != null) {
-              int fieldOrdinal = global::System.Array.BinarySearch(_fieldNames, fieldName, global::System.StringComparer.Ordinal);
-              if (fieldOrdinal >= 0) {
-                tag = _fieldTags[fieldOrdinal];
-              }
-            }
+          while (input.ReadTag(out tag)) {
             switch(tag) {
               case 0:
                 throw pb::InvalidProtocolBufferException.InvalidTag();
@@ -3296,11 +3171,11 @@
                 }
                 break;
               case 8: {
-                input.ReadInt32(ref bb_);
+                bb_ = input.ReadInt32();
                 break;
               }
               case 16: {
-                input.ReadInt64(ref oo_);
+                oo_ = input.ReadInt64();
                 break;
               }
             }
@@ -3362,10 +3237,9 @@
       return hash;
     }
 
-    public void WriteTo(pb::ICodedOutputStream output) {
-      string[] fieldNames = _fieldNames;
+    public void WriteTo(pb::CodedOutputStream output) {
       if (SparseEnum != global::Google.Protobuf.TestProtos.TestSparseEnum.TEST_SPARSE_ENUM_UNSPECIFIED) {
-        output.WriteEnum(1, fieldNames[0], (int) SparseEnum);
+        output.WriteEnum(1, (int) SparseEnum);
       }
     }
 
@@ -3385,16 +3259,9 @@
       }
     }
 
-    public void MergeFrom(pb::ICodedInputStream input) {
+    public void MergeFrom(pb::CodedInputStream input) {
       uint tag;
-      string fieldName;
-      while (input.ReadTag(out tag, out fieldName)) {
-        if (tag == 0 && fieldName != null) {
-          int fieldOrdinal = global::System.Array.BinarySearch(_fieldNames, fieldName, global::System.StringComparer.Ordinal);
-          if (fieldOrdinal >= 0) {
-            tag = _fieldTags[fieldOrdinal];
-          }
-        }
+      while (input.ReadTag(out tag)) {
         switch(tag) {
           case 0:
             throw pb::InvalidProtocolBufferException.InvalidTag();
@@ -3404,9 +3271,8 @@
             }
             break;
           case 8: {
-            int tmp = 0;
-            input.ReadEnum(ref tmp);
-            sparseEnum_ = (global::Google.Protobuf.TestProtos.TestSparseEnum) tmp;break;
+            sparseEnum_ = (global::Google.Protobuf.TestProtos.TestSparseEnum) input.ReadEnum();
+            break;
           }
         }
       }
@@ -3462,10 +3328,9 @@
       return hash;
     }
 
-    public void WriteTo(pb::ICodedOutputStream output) {
-      string[] fieldNames = _fieldNames;
+    public void WriteTo(pb::CodedOutputStream output) {
       if (Data != "") {
-        output.WriteString(1, fieldNames[0], Data);
+        output.WriteString(1, Data);
       }
     }
 
@@ -3485,16 +3350,9 @@
       }
     }
 
-    public void MergeFrom(pb::ICodedInputStream input) {
+    public void MergeFrom(pb::CodedInputStream input) {
       uint tag;
-      string fieldName;
-      while (input.ReadTag(out tag, out fieldName)) {
-        if (tag == 0 && fieldName != null) {
-          int fieldOrdinal = global::System.Array.BinarySearch(_fieldNames, fieldName, global::System.StringComparer.Ordinal);
-          if (fieldOrdinal >= 0) {
-            tag = _fieldTags[fieldOrdinal];
-          }
-        }
+      while (input.ReadTag(out tag)) {
         switch(tag) {
           case 0:
             throw pb::InvalidProtocolBufferException.InvalidTag();
@@ -3504,7 +3362,7 @@
             }
             break;
           case 10: {
-            input.ReadString(ref data_);
+            data_ = input.ReadString();
             break;
           }
         }
@@ -3559,9 +3417,8 @@
       return hash;
     }
 
-    public void WriteTo(pb::ICodedOutputStream output) {
-      string[] fieldNames = _fieldNames;
-      output.WriteStringArray(1, fieldNames[0], data_);
+    public void WriteTo(pb::CodedOutputStream output) {
+      output.WriteStringArray(1, data_);
     }
 
     public int CalculateSize() {
@@ -3583,16 +3440,9 @@
       data_.Add(other.data_);
     }
 
-    public void MergeFrom(pb::ICodedInputStream input) {
+    public void MergeFrom(pb::CodedInputStream input) {
       uint tag;
-      string fieldName;
-      while (input.ReadTag(out tag, out fieldName)) {
-        if (tag == 0 && fieldName != null) {
-          int fieldOrdinal = global::System.Array.BinarySearch(_fieldNames, fieldName, global::System.StringComparer.Ordinal);
-          if (fieldOrdinal >= 0) {
-            tag = _fieldTags[fieldOrdinal];
-          }
-        }
+      while (input.ReadTag(out tag)) {
         switch(tag) {
           case 0:
             throw pb::InvalidProtocolBufferException.InvalidTag();
@@ -3602,7 +3452,7 @@
             }
             break;
           case 10: {
-            input.ReadStringArray(tag, fieldName, data_);
+            input.ReadStringArray(tag, data_);
             break;
           }
         }
@@ -3659,10 +3509,9 @@
       return hash;
     }
 
-    public void WriteTo(pb::ICodedOutputStream output) {
-      string[] fieldNames = _fieldNames;
+    public void WriteTo(pb::CodedOutputStream output) {
       if (Data != pb::ByteString.Empty) {
-        output.WriteBytes(1, fieldNames[0], Data);
+        output.WriteBytes(1, Data);
       }
     }
 
@@ -3682,16 +3531,9 @@
       }
     }
 
-    public void MergeFrom(pb::ICodedInputStream input) {
+    public void MergeFrom(pb::CodedInputStream input) {
       uint tag;
-      string fieldName;
-      while (input.ReadTag(out tag, out fieldName)) {
-        if (tag == 0 && fieldName != null) {
-          int fieldOrdinal = global::System.Array.BinarySearch(_fieldNames, fieldName, global::System.StringComparer.Ordinal);
-          if (fieldOrdinal >= 0) {
-            tag = _fieldTags[fieldOrdinal];
-          }
-        }
+      while (input.ReadTag(out tag)) {
         switch(tag) {
           case 0:
             throw pb::InvalidProtocolBufferException.InvalidTag();
@@ -3701,7 +3543,7 @@
             }
             break;
           case 10: {
-            input.ReadBytes(ref data_);
+            data_ = input.ReadBytes();
             break;
           }
         }
@@ -3758,10 +3600,9 @@
       return hash;
     }
 
-    public void WriteTo(pb::ICodedOutputStream output) {
-      string[] fieldNames = _fieldNames;
+    public void WriteTo(pb::CodedOutputStream output) {
       if (Data != pb::ByteString.Empty) {
-        output.WriteBytes(1, fieldNames[0], Data);
+        output.WriteBytes(1, Data);
       }
     }
 
@@ -3781,16 +3622,9 @@
       }
     }
 
-    public void MergeFrom(pb::ICodedInputStream input) {
+    public void MergeFrom(pb::CodedInputStream input) {
       uint tag;
-      string fieldName;
-      while (input.ReadTag(out tag, out fieldName)) {
-        if (tag == 0 && fieldName != null) {
-          int fieldOrdinal = global::System.Array.BinarySearch(_fieldNames, fieldName, global::System.StringComparer.Ordinal);
-          if (fieldOrdinal >= 0) {
-            tag = _fieldTags[fieldOrdinal];
-          }
-        }
+      while (input.ReadTag(out tag)) {
         switch(tag) {
           case 0:
             throw pb::InvalidProtocolBufferException.InvalidTag();
@@ -3800,7 +3634,7 @@
             }
             break;
           case 10: {
-            input.ReadBytes(ref data_);
+            data_ = input.ReadBytes();
             break;
           }
         }
@@ -3857,10 +3691,9 @@
       return hash;
     }
 
-    public void WriteTo(pb::ICodedOutputStream output) {
-      string[] fieldNames = _fieldNames;
+    public void WriteTo(pb::CodedOutputStream output) {
       if (Data != 0) {
-        output.WriteInt32(1, fieldNames[0], Data);
+        output.WriteInt32(1, Data);
       }
     }
 
@@ -3880,16 +3713,9 @@
       }
     }
 
-    public void MergeFrom(pb::ICodedInputStream input) {
+    public void MergeFrom(pb::CodedInputStream input) {
       uint tag;
-      string fieldName;
-      while (input.ReadTag(out tag, out fieldName)) {
-        if (tag == 0 && fieldName != null) {
-          int fieldOrdinal = global::System.Array.BinarySearch(_fieldNames, fieldName, global::System.StringComparer.Ordinal);
-          if (fieldOrdinal >= 0) {
-            tag = _fieldTags[fieldOrdinal];
-          }
-        }
+      while (input.ReadTag(out tag)) {
         switch(tag) {
           case 0:
             throw pb::InvalidProtocolBufferException.InvalidTag();
@@ -3899,7 +3725,7 @@
             }
             break;
           case 8: {
-            input.ReadInt32(ref data_);
+            data_ = input.ReadInt32();
             break;
           }
         }
@@ -3956,10 +3782,9 @@
       return hash;
     }
 
-    public void WriteTo(pb::ICodedOutputStream output) {
-      string[] fieldNames = _fieldNames;
+    public void WriteTo(pb::CodedOutputStream output) {
       if (Data != 0) {
-        output.WriteUInt32(1, fieldNames[0], Data);
+        output.WriteUInt32(1, Data);
       }
     }
 
@@ -3979,16 +3804,9 @@
       }
     }
 
-    public void MergeFrom(pb::ICodedInputStream input) {
+    public void MergeFrom(pb::CodedInputStream input) {
       uint tag;
-      string fieldName;
-      while (input.ReadTag(out tag, out fieldName)) {
-        if (tag == 0 && fieldName != null) {
-          int fieldOrdinal = global::System.Array.BinarySearch(_fieldNames, fieldName, global::System.StringComparer.Ordinal);
-          if (fieldOrdinal >= 0) {
-            tag = _fieldTags[fieldOrdinal];
-          }
-        }
+      while (input.ReadTag(out tag)) {
         switch(tag) {
           case 0:
             throw pb::InvalidProtocolBufferException.InvalidTag();
@@ -3998,7 +3816,7 @@
             }
             break;
           case 8: {
-            input.ReadUInt32(ref data_);
+            data_ = input.ReadUInt32();
             break;
           }
         }
@@ -4055,10 +3873,9 @@
       return hash;
     }
 
-    public void WriteTo(pb::ICodedOutputStream output) {
-      string[] fieldNames = _fieldNames;
+    public void WriteTo(pb::CodedOutputStream output) {
       if (Data != 0L) {
-        output.WriteInt64(1, fieldNames[0], Data);
+        output.WriteInt64(1, Data);
       }
     }
 
@@ -4078,16 +3895,9 @@
       }
     }
 
-    public void MergeFrom(pb::ICodedInputStream input) {
+    public void MergeFrom(pb::CodedInputStream input) {
       uint tag;
-      string fieldName;
-      while (input.ReadTag(out tag, out fieldName)) {
-        if (tag == 0 && fieldName != null) {
-          int fieldOrdinal = global::System.Array.BinarySearch(_fieldNames, fieldName, global::System.StringComparer.Ordinal);
-          if (fieldOrdinal >= 0) {
-            tag = _fieldTags[fieldOrdinal];
-          }
-        }
+      while (input.ReadTag(out tag)) {
         switch(tag) {
           case 0:
             throw pb::InvalidProtocolBufferException.InvalidTag();
@@ -4097,7 +3907,7 @@
             }
             break;
           case 8: {
-            input.ReadInt64(ref data_);
+            data_ = input.ReadInt64();
             break;
           }
         }
@@ -4154,10 +3964,9 @@
       return hash;
     }
 
-    public void WriteTo(pb::ICodedOutputStream output) {
-      string[] fieldNames = _fieldNames;
+    public void WriteTo(pb::CodedOutputStream output) {
       if (Data != 0UL) {
-        output.WriteUInt64(1, fieldNames[0], Data);
+        output.WriteUInt64(1, Data);
       }
     }
 
@@ -4177,16 +3986,9 @@
       }
     }
 
-    public void MergeFrom(pb::ICodedInputStream input) {
+    public void MergeFrom(pb::CodedInputStream input) {
       uint tag;
-      string fieldName;
-      while (input.ReadTag(out tag, out fieldName)) {
-        if (tag == 0 && fieldName != null) {
-          int fieldOrdinal = global::System.Array.BinarySearch(_fieldNames, fieldName, global::System.StringComparer.Ordinal);
-          if (fieldOrdinal >= 0) {
-            tag = _fieldTags[fieldOrdinal];
-          }
-        }
+      while (input.ReadTag(out tag)) {
         switch(tag) {
           case 0:
             throw pb::InvalidProtocolBufferException.InvalidTag();
@@ -4196,7 +3998,7 @@
             }
             break;
           case 8: {
-            input.ReadUInt64(ref data_);
+            data_ = input.ReadUInt64();
             break;
           }
         }
@@ -4253,10 +4055,9 @@
       return hash;
     }
 
-    public void WriteTo(pb::ICodedOutputStream output) {
-      string[] fieldNames = _fieldNames;
+    public void WriteTo(pb::CodedOutputStream output) {
       if (Data != false) {
-        output.WriteBool(1, fieldNames[0], Data);
+        output.WriteBool(1, Data);
       }
     }
 
@@ -4276,16 +4077,9 @@
       }
     }
 
-    public void MergeFrom(pb::ICodedInputStream input) {
+    public void MergeFrom(pb::CodedInputStream input) {
       uint tag;
-      string fieldName;
-      while (input.ReadTag(out tag, out fieldName)) {
-        if (tag == 0 && fieldName != null) {
-          int fieldOrdinal = global::System.Array.BinarySearch(_fieldNames, fieldName, global::System.StringComparer.Ordinal);
-          if (fieldOrdinal >= 0) {
-            tag = _fieldTags[fieldOrdinal];
-          }
-        }
+      while (input.ReadTag(out tag)) {
         switch(tag) {
           case 0:
             throw pb::InvalidProtocolBufferException.InvalidTag();
@@ -4295,7 +4089,7 @@
             }
             break;
           case 8: {
-            input.ReadBool(ref data_);
+            data_ = input.ReadBool();
             break;
           }
         }
@@ -4391,16 +4185,15 @@
       return hash;
     }
 
-    public void WriteTo(pb::ICodedOutputStream output) {
-      string[] fieldNames = _fieldNames;
+    public void WriteTo(pb::CodedOutputStream output) {
       if (fooCase_ == FooOneofCase.FooInt) {
-        output.WriteInt32(1, fieldNames[0], FooInt);
+        output.WriteInt32(1, FooInt);
       }
       if (fooCase_ == FooOneofCase.FooString) {
-        output.WriteString(2, fieldNames[2], FooString);
+        output.WriteString(2, FooString);
       }
       if (fooCase_ == FooOneofCase.FooMessage) {
-        output.WriteMessage(3, fieldNames[1], FooMessage);
+        output.WriteMessage(3, FooMessage);
       }
     }
 
@@ -4435,16 +4228,9 @@
 
     }
 
-    public void MergeFrom(pb::ICodedInputStream input) {
+    public void MergeFrom(pb::CodedInputStream input) {
       uint tag;
-      string fieldName;
-      while (input.ReadTag(out tag, out fieldName)) {
-        if (tag == 0 && fieldName != null) {
-          int fieldOrdinal = global::System.Array.BinarySearch(_fieldNames, fieldName, global::System.StringComparer.Ordinal);
-          if (fieldOrdinal >= 0) {
-            tag = _fieldTags[fieldOrdinal];
-          }
-        }
+      while (input.ReadTag(out tag)) {
         switch(tag) {
           case 0:
             throw pb::InvalidProtocolBufferException.InvalidTag();
@@ -4454,19 +4240,13 @@
             }
             break;
           case 8: {
-            int value = 0;
-            if (input.ReadInt32(ref value)) {
-              foo_ = value;
-              fooCase_ = FooOneofCase.FooInt;
-            }
+            foo_ = input.ReadInt32()
+            ;fooCase_ = FooOneofCase.FooInt;
             break;
           }
           case 18: {
-            string value = "";
-            if (input.ReadString(ref value)) {
-              foo_ = value;
-              fooCase_ = FooOneofCase.FooString;
-            }
+            foo_ = input.ReadString()
+            ;fooCase_ = FooOneofCase.FooString;
             break;
           }
           case 26: {
@@ -4634,22 +4414,21 @@
       return hash;
     }
 
-    public void WriteTo(pb::ICodedOutputStream output) {
-      string[] fieldNames = _fieldNames;
-      output.WritePackedInt32Array(90, fieldNames[6], packedInt32_);
-      output.WritePackedInt64Array(91, fieldNames[7], packedInt64_);
-      output.WritePackedUInt32Array(92, fieldNames[12], packedUint32_);
-      output.WritePackedUInt64Array(93, fieldNames[13], packedUint64_);
-      output.WritePackedSInt32Array(94, fieldNames[10], packedSint32_);
-      output.WritePackedSInt64Array(95, fieldNames[11], packedSint64_);
-      output.WritePackedFixed32Array(96, fieldNames[3], packedFixed32_);
-      output.WritePackedFixed64Array(97, fieldNames[4], packedFixed64_);
-      output.WritePackedSFixed32Array(98, fieldNames[8], packedSfixed32_);
-      output.WritePackedSFixed64Array(99, fieldNames[9], packedSfixed64_);
-      output.WritePackedFloatArray(100, fieldNames[5], packedFloat_);
-      output.WritePackedDoubleArray(101, fieldNames[1], packedDouble_);
-      output.WritePackedBoolArray(102, fieldNames[0], packedBool_);
-      output.WritePackedEnumArray(103, fieldNames[2], packedEnum_);
+    public void WriteTo(pb::CodedOutputStream output) {
+      output.WritePackedInt32Array(90, packedInt32_);
+      output.WritePackedInt64Array(91, packedInt64_);
+      output.WritePackedUInt32Array(92, packedUint32_);
+      output.WritePackedUInt64Array(93, packedUint64_);
+      output.WritePackedSInt32Array(94, packedSint32_);
+      output.WritePackedSInt64Array(95, packedSint64_);
+      output.WritePackedFixed32Array(96, packedFixed32_);
+      output.WritePackedFixed64Array(97, packedFixed64_);
+      output.WritePackedSFixed32Array(98, packedSfixed32_);
+      output.WritePackedSFixed64Array(99, packedSfixed64_);
+      output.WritePackedFloatArray(100, packedFloat_);
+      output.WritePackedDoubleArray(101, packedDouble_);
+      output.WritePackedBoolArray(102, packedBool_);
+      output.WritePackedEnumArray(103, packedEnum_);
     }
 
     public int CalculateSize() {
@@ -4803,16 +4582,9 @@
       packedEnum_.Add(other.packedEnum_);
     }
 
-    public void MergeFrom(pb::ICodedInputStream input) {
+    public void MergeFrom(pb::CodedInputStream input) {
       uint tag;
-      string fieldName;
-      while (input.ReadTag(out tag, out fieldName)) {
-        if (tag == 0 && fieldName != null) {
-          int fieldOrdinal = global::System.Array.BinarySearch(_fieldNames, fieldName, global::System.StringComparer.Ordinal);
-          if (fieldOrdinal >= 0) {
-            tag = _fieldTags[fieldOrdinal];
-          }
-        }
+      while (input.ReadTag(out tag)) {
         switch(tag) {
           case 0:
             throw pb::InvalidProtocolBufferException.InvalidTag();
@@ -4823,72 +4595,72 @@
             break;
           case 722:
           case 720: {
-            input.ReadInt32Array(tag, fieldName, packedInt32_);
+            input.ReadInt32Array(tag, packedInt32_);
             break;
           }
           case 730:
           case 728: {
-            input.ReadInt64Array(tag, fieldName, packedInt64_);
+            input.ReadInt64Array(tag, packedInt64_);
             break;
           }
           case 738:
           case 736: {
-            input.ReadUInt32Array(tag, fieldName, packedUint32_);
+            input.ReadUInt32Array(tag, packedUint32_);
             break;
           }
           case 746:
           case 744: {
-            input.ReadUInt64Array(tag, fieldName, packedUint64_);
+            input.ReadUInt64Array(tag, packedUint64_);
             break;
           }
           case 754:
           case 752: {
-            input.ReadSInt32Array(tag, fieldName, packedSint32_);
+            input.ReadSInt32Array(tag, packedSint32_);
             break;
           }
           case 762:
           case 760: {
-            input.ReadSInt64Array(tag, fieldName, packedSint64_);
+            input.ReadSInt64Array(tag, packedSint64_);
             break;
           }
           case 770:
           case 773: {
-            input.ReadFixed32Array(tag, fieldName, packedFixed32_);
+            input.ReadFixed32Array(tag, packedFixed32_);
             break;
           }
           case 778:
           case 777: {
-            input.ReadFixed64Array(tag, fieldName, packedFixed64_);
+            input.ReadFixed64Array(tag, packedFixed64_);
             break;
           }
           case 786:
           case 789: {
-            input.ReadSFixed32Array(tag, fieldName, packedSfixed32_);
+            input.ReadSFixed32Array(tag, packedSfixed32_);
             break;
           }
           case 794:
           case 793: {
-            input.ReadSFixed64Array(tag, fieldName, packedSfixed64_);
+            input.ReadSFixed64Array(tag, packedSfixed64_);
             break;
           }
           case 802:
           case 805: {
-            input.ReadFloatArray(tag, fieldName, packedFloat_);
+            input.ReadFloatArray(tag, packedFloat_);
             break;
           }
           case 810:
           case 809: {
-            input.ReadDoubleArray(tag, fieldName, packedDouble_);
+            input.ReadDoubleArray(tag, packedDouble_);
             break;
           }
           case 818:
           case 816: {
-            input.ReadBoolArray(tag, fieldName, packedBool_);
+            input.ReadBoolArray(tag, packedBool_);
             break;
           }
           case 826:
           case 824: {
-            input.ReadEnumArray<global::Google.Protobuf.TestProtos.ForeignEnum>(tag, fieldName, packedEnum_);
+            input.ReadEnumArray<global::Google.Protobuf.TestProtos.ForeignEnum>(tag, packedEnum_);
             break;
           }
         }
@@ -5047,22 +4819,21 @@
       return hash;
     }
 
-    public void WriteTo(pb::ICodedOutputStream output) {
-      string[] fieldNames = _fieldNames;
-      output.WriteInt32Array(90, fieldNames[6], unpackedInt32_);
-      output.WriteInt64Array(91, fieldNames[7], unpackedInt64_);
-      output.WriteUInt32Array(92, fieldNames[12], unpackedUint32_);
-      output.WriteUInt64Array(93, fieldNames[13], unpackedUint64_);
-      output.WriteSInt32Array(94, fieldNames[10], unpackedSint32_);
-      output.WriteSInt64Array(95, fieldNames[11], unpackedSint64_);
-      output.WriteFixed32Array(96, fieldNames[3], unpackedFixed32_);
-      output.WriteFixed64Array(97, fieldNames[4], unpackedFixed64_);
-      output.WriteSFixed32Array(98, fieldNames[8], unpackedSfixed32_);
-      output.WriteSFixed64Array(99, fieldNames[9], unpackedSfixed64_);
-      output.WriteFloatArray(100, fieldNames[5], unpackedFloat_);
-      output.WriteDoubleArray(101, fieldNames[1], unpackedDouble_);
-      output.WriteBoolArray(102, fieldNames[0], unpackedBool_);
-      output.WriteEnumArray(103, fieldNames[2], unpackedEnum_);
+    public void WriteTo(pb::CodedOutputStream output) {
+      output.WriteInt32Array(90, unpackedInt32_);
+      output.WriteInt64Array(91, unpackedInt64_);
+      output.WriteUInt32Array(92, unpackedUint32_);
+      output.WriteUInt64Array(93, unpackedUint64_);
+      output.WriteSInt32Array(94, unpackedSint32_);
+      output.WriteSInt64Array(95, unpackedSint64_);
+      output.WriteFixed32Array(96, unpackedFixed32_);
+      output.WriteFixed64Array(97, unpackedFixed64_);
+      output.WriteSFixed32Array(98, unpackedSfixed32_);
+      output.WriteSFixed64Array(99, unpackedSfixed64_);
+      output.WriteFloatArray(100, unpackedFloat_);
+      output.WriteDoubleArray(101, unpackedDouble_);
+      output.WriteBoolArray(102, unpackedBool_);
+      output.WriteEnumArray(103, unpackedEnum_);
     }
 
     public int CalculateSize() {
@@ -5189,16 +4960,9 @@
       unpackedEnum_.Add(other.unpackedEnum_);
     }
 
-    public void MergeFrom(pb::ICodedInputStream input) {
+    public void MergeFrom(pb::CodedInputStream input) {
       uint tag;
-      string fieldName;
-      while (input.ReadTag(out tag, out fieldName)) {
-        if (tag == 0 && fieldName != null) {
-          int fieldOrdinal = global::System.Array.BinarySearch(_fieldNames, fieldName, global::System.StringComparer.Ordinal);
-          if (fieldOrdinal >= 0) {
-            tag = _fieldTags[fieldOrdinal];
-          }
-        }
+      while (input.ReadTag(out tag)) {
         switch(tag) {
           case 0:
             throw pb::InvalidProtocolBufferException.InvalidTag();
@@ -5209,72 +4973,72 @@
             break;
           case 722:
           case 720: {
-            input.ReadInt32Array(tag, fieldName, unpackedInt32_);
+            input.ReadInt32Array(tag, unpackedInt32_);
             break;
           }
           case 730:
           case 728: {
-            input.ReadInt64Array(tag, fieldName, unpackedInt64_);
+            input.ReadInt64Array(tag, unpackedInt64_);
             break;
           }
           case 738:
           case 736: {
-            input.ReadUInt32Array(tag, fieldName, unpackedUint32_);
+            input.ReadUInt32Array(tag, unpackedUint32_);
             break;
           }
           case 746:
           case 744: {
-            input.ReadUInt64Array(tag, fieldName, unpackedUint64_);
+            input.ReadUInt64Array(tag, unpackedUint64_);
             break;
           }
           case 754:
           case 752: {
-            input.ReadSInt32Array(tag, fieldName, unpackedSint32_);
+            input.ReadSInt32Array(tag, unpackedSint32_);
             break;
           }
           case 762:
           case 760: {
-            input.ReadSInt64Array(tag, fieldName, unpackedSint64_);
+            input.ReadSInt64Array(tag, unpackedSint64_);
             break;
           }
           case 770:
           case 773: {
-            input.ReadFixed32Array(tag, fieldName, unpackedFixed32_);
+            input.ReadFixed32Array(tag, unpackedFixed32_);
             break;
           }
           case 778:
           case 777: {
-            input.ReadFixed64Array(tag, fieldName, unpackedFixed64_);
+            input.ReadFixed64Array(tag, unpackedFixed64_);
             break;
           }
           case 786:
           case 789: {
-            input.ReadSFixed32Array(tag, fieldName, unpackedSfixed32_);
+            input.ReadSFixed32Array(tag, unpackedSfixed32_);
             break;
           }
           case 794:
           case 793: {
-            input.ReadSFixed64Array(tag, fieldName, unpackedSfixed64_);
+            input.ReadSFixed64Array(tag, unpackedSfixed64_);
             break;
           }
           case 802:
           case 805: {
-            input.ReadFloatArray(tag, fieldName, unpackedFloat_);
+            input.ReadFloatArray(tag, unpackedFloat_);
             break;
           }
           case 810:
           case 809: {
-            input.ReadDoubleArray(tag, fieldName, unpackedDouble_);
+            input.ReadDoubleArray(tag, unpackedDouble_);
             break;
           }
           case 818:
           case 816: {
-            input.ReadBoolArray(tag, fieldName, unpackedBool_);
+            input.ReadBoolArray(tag, unpackedBool_);
             break;
           }
           case 826:
           case 824: {
-            input.ReadEnumArray<global::Google.Protobuf.TestProtos.ForeignEnum>(tag, fieldName, unpackedEnum_);
+            input.ReadEnumArray<global::Google.Protobuf.TestProtos.ForeignEnum>(tag, unpackedEnum_);
             break;
           }
         }
@@ -5369,14 +5133,13 @@
       return hash;
     }
 
-    public void WriteTo(pb::ICodedOutputStream output) {
-      string[] fieldNames = _fieldNames;
-      output.WritePackedFixed32Array(12, fieldNames[0], repeatedFixed32_);
-      output.WritePackedInt32Array(13, fieldNames[3], repeatedInt32_);
-      output.WritePackedFixed64Array(2046, fieldNames[1], repeatedFixed64_);
-      output.WritePackedInt64Array(2047, fieldNames[4], repeatedInt64_);
-      output.WritePackedFloatArray(262142, fieldNames[2], repeatedFloat_);
-      output.WritePackedUInt64Array(262143, fieldNames[5], repeatedUint64_);
+    public void WriteTo(pb::CodedOutputStream output) {
+      output.WritePackedFixed32Array(12, repeatedFixed32_);
+      output.WritePackedInt32Array(13, repeatedInt32_);
+      output.WritePackedFixed64Array(2046, repeatedFixed64_);
+      output.WritePackedInt64Array(2047, repeatedInt64_);
+      output.WritePackedFloatArray(262142, repeatedFloat_);
+      output.WritePackedUInt64Array(262143, repeatedUint64_);
     }
 
     public int CalculateSize() {
@@ -5449,16 +5212,9 @@
       repeatedUint64_.Add(other.repeatedUint64_);
     }
 
-    public void MergeFrom(pb::ICodedInputStream input) {
+    public void MergeFrom(pb::CodedInputStream input) {
       uint tag;
-      string fieldName;
-      while (input.ReadTag(out tag, out fieldName)) {
-        if (tag == 0 && fieldName != null) {
-          int fieldOrdinal = global::System.Array.BinarySearch(_fieldNames, fieldName, global::System.StringComparer.Ordinal);
-          if (fieldOrdinal >= 0) {
-            tag = _fieldTags[fieldOrdinal];
-          }
-        }
+      while (input.ReadTag(out tag)) {
         switch(tag) {
           case 0:
             throw pb::InvalidProtocolBufferException.InvalidTag();
@@ -5469,32 +5225,32 @@
             break;
           case 98:
           case 101: {
-            input.ReadFixed32Array(tag, fieldName, repeatedFixed32_);
+            input.ReadFixed32Array(tag, repeatedFixed32_);
             break;
           }
           case 106:
           case 104: {
-            input.ReadInt32Array(tag, fieldName, repeatedInt32_);
+            input.ReadInt32Array(tag, repeatedInt32_);
             break;
           }
           case 16370:
           case 16369: {
-            input.ReadFixed64Array(tag, fieldName, repeatedFixed64_);
+            input.ReadFixed64Array(tag, repeatedFixed64_);
             break;
           }
           case 16378:
           case 16376: {
-            input.ReadInt64Array(tag, fieldName, repeatedInt64_);
+            input.ReadInt64Array(tag, repeatedInt64_);
             break;
           }
           case 2097138:
           case 2097141: {
-            input.ReadFloatArray(tag, fieldName, repeatedFloat_);
+            input.ReadFloatArray(tag, repeatedFloat_);
             break;
           }
           case 2097146:
           case 2097144: {
-            input.ReadUInt64Array(tag, fieldName, repeatedUint64_);
+            input.ReadUInt64Array(tag, repeatedUint64_);
             break;
           }
         }
@@ -5551,10 +5307,9 @@
       return hash;
     }
 
-    public void WriteTo(pb::ICodedOutputStream output) {
-      string[] fieldNames = _fieldNames;
+    public void WriteTo(pb::CodedOutputStream output) {
       if (A != "") {
-        output.WriteString(1, fieldNames[0], A);
+        output.WriteString(1, A);
       }
     }
 
@@ -5574,16 +5329,9 @@
       }
     }
 
-    public void MergeFrom(pb::ICodedInputStream input) {
+    public void MergeFrom(pb::CodedInputStream input) {
       uint tag;
-      string fieldName;
-      while (input.ReadTag(out tag, out fieldName)) {
-        if (tag == 0 && fieldName != null) {
-          int fieldOrdinal = global::System.Array.BinarySearch(_fieldNames, fieldName, global::System.StringComparer.Ordinal);
-          if (fieldOrdinal >= 0) {
-            tag = _fieldTags[fieldOrdinal];
-          }
-        }
+      while (input.ReadTag(out tag)) {
         switch(tag) {
           case 0:
             throw pb::InvalidProtocolBufferException.InvalidTag();
@@ -5593,7 +5341,7 @@
             }
             break;
           case 10: {
-            input.ReadString(ref a_);
+            a_ = input.ReadString();
             break;
           }
         }
@@ -5640,8 +5388,7 @@
       return hash;
     }
 
-    public void WriteTo(pb::ICodedOutputStream output) {
-      string[] fieldNames = _fieldNames;
+    public void WriteTo(pb::CodedOutputStream output) {
     }
 
     public int CalculateSize() {
@@ -5654,16 +5401,9 @@
       }
     }
 
-    public void MergeFrom(pb::ICodedInputStream input) {
+    public void MergeFrom(pb::CodedInputStream input) {
       uint tag;
-      string fieldName;
-      while (input.ReadTag(out tag, out fieldName)) {
-        if (tag == 0 && fieldName != null) {
-          int fieldOrdinal = global::System.Array.BinarySearch(_fieldNames, fieldName, global::System.StringComparer.Ordinal);
-          if (fieldOrdinal >= 0) {
-            tag = _fieldTags[fieldOrdinal];
-          }
-        }
+      while (input.ReadTag(out tag)) {
         switch(tag) {
           case 0:
             throw pb::InvalidProtocolBufferException.InvalidTag();
@@ -5716,8 +5456,7 @@
       return hash;
     }
 
-    public void WriteTo(pb::ICodedOutputStream output) {
-      string[] fieldNames = _fieldNames;
+    public void WriteTo(pb::CodedOutputStream output) {
     }
 
     public int CalculateSize() {
@@ -5730,16 +5469,9 @@
       }
     }
 
-    public void MergeFrom(pb::ICodedInputStream input) {
+    public void MergeFrom(pb::CodedInputStream input) {
       uint tag;
-      string fieldName;
-      while (input.ReadTag(out tag, out fieldName)) {
-        if (tag == 0 && fieldName != null) {
-          int fieldOrdinal = global::System.Array.BinarySearch(_fieldNames, fieldName, global::System.StringComparer.Ordinal);
-          if (fieldOrdinal >= 0) {
-            tag = _fieldTags[fieldOrdinal];
-          }
-        }
+      while (input.ReadTag(out tag)) {
         switch(tag) {
           case 0:
             throw pb::InvalidProtocolBufferException.InvalidTag();
@@ -5792,8 +5524,7 @@
       return hash;
     }
 
-    public void WriteTo(pb::ICodedOutputStream output) {
-      string[] fieldNames = _fieldNames;
+    public void WriteTo(pb::CodedOutputStream output) {
     }
 
     public int CalculateSize() {
@@ -5806,16 +5537,9 @@
       }
     }
 
-    public void MergeFrom(pb::ICodedInputStream input) {
+    public void MergeFrom(pb::CodedInputStream input) {
       uint tag;
-      string fieldName;
-      while (input.ReadTag(out tag, out fieldName)) {
-        if (tag == 0 && fieldName != null) {
-          int fieldOrdinal = global::System.Array.BinarySearch(_fieldNames, fieldName, global::System.StringComparer.Ordinal);
-          if (fieldOrdinal >= 0) {
-            tag = _fieldTags[fieldOrdinal];
-          }
-        }
+      while (input.ReadTag(out tag)) {
         switch(tag) {
           case 0:
             throw pb::InvalidProtocolBufferException.InvalidTag();
@@ -5868,8 +5592,7 @@
       return hash;
     }
 
-    public void WriteTo(pb::ICodedOutputStream output) {
-      string[] fieldNames = _fieldNames;
+    public void WriteTo(pb::CodedOutputStream output) {
     }
 
     public int CalculateSize() {
@@ -5882,16 +5605,9 @@
       }
     }
 
-    public void MergeFrom(pb::ICodedInputStream input) {
+    public void MergeFrom(pb::CodedInputStream input) {
       uint tag;
-      string fieldName;
-      while (input.ReadTag(out tag, out fieldName)) {
-        if (tag == 0 && fieldName != null) {
-          int fieldOrdinal = global::System.Array.BinarySearch(_fieldNames, fieldName, global::System.StringComparer.Ordinal);
-          if (fieldOrdinal >= 0) {
-            tag = _fieldTags[fieldOrdinal];
-          }
-        }
+      while (input.ReadTag(out tag)) {
         switch(tag) {
           case 0:
             throw pb::InvalidProtocolBufferException.InvalidTag();
@@ -5944,8 +5660,7 @@
       return hash;
     }
 
-    public void WriteTo(pb::ICodedOutputStream output) {
-      string[] fieldNames = _fieldNames;
+    public void WriteTo(pb::CodedOutputStream output) {
     }
 
     public int CalculateSize() {
@@ -5958,16 +5673,9 @@
       }
     }
 
-    public void MergeFrom(pb::ICodedInputStream input) {
+    public void MergeFrom(pb::CodedInputStream input) {
       uint tag;
-      string fieldName;
-      while (input.ReadTag(out tag, out fieldName)) {
-        if (tag == 0 && fieldName != null) {
-          int fieldOrdinal = global::System.Array.BinarySearch(_fieldNames, fieldName, global::System.StringComparer.Ordinal);
-          if (fieldOrdinal >= 0) {
-            tag = _fieldTags[fieldOrdinal];
-          }
-        }
+      while (input.ReadTag(out tag)) {
         switch(tag) {
           case 0:
             throw pb::InvalidProtocolBufferException.InvalidTag();
@@ -6020,8 +5728,7 @@
       return hash;
     }
 
-    public void WriteTo(pb::ICodedOutputStream output) {
-      string[] fieldNames = _fieldNames;
+    public void WriteTo(pb::CodedOutputStream output) {
     }
 
     public int CalculateSize() {
@@ -6034,16 +5741,9 @@
       }
     }
 
-    public void MergeFrom(pb::ICodedInputStream input) {
+    public void MergeFrom(pb::CodedInputStream input) {
       uint tag;
-      string fieldName;
-      while (input.ReadTag(out tag, out fieldName)) {
-        if (tag == 0 && fieldName != null) {
-          int fieldOrdinal = global::System.Array.BinarySearch(_fieldNames, fieldName, global::System.StringComparer.Ordinal);
-          if (fieldOrdinal >= 0) {
-            tag = _fieldTags[fieldOrdinal];
-          }
-        }
+      while (input.ReadTag(out tag)) {
         switch(tag) {
           case 0:
             throw pb::InvalidProtocolBufferException.InvalidTag();
diff --git a/csharp/src/ProtocolBuffers/CodedInputStream.cs b/csharp/src/ProtocolBuffers/CodedInputStream.cs
index d5cab6f..cb47f1c 100644
--- a/csharp/src/ProtocolBuffers/CodedInputStream.cs
+++ b/csharp/src/ProtocolBuffers/CodedInputStream.cs
@@ -58,7 +58,7 @@
     /// TODO(jonskeet): Consider whether recursion and size limits shouldn't be readonly,

     /// set at construction time.

     /// </remarks>

-    public sealed class CodedInputStream : ICodedInputStream

+    public sealed class CodedInputStream

     {

         private readonly byte[] buffer;

         private int bufferSize;

@@ -173,10 +173,6 @@
             }

         }

 

-

-        void ICodedInputStream.ReadMessageStart() { }

-        void ICodedInputStream.ReadMessageEnd() { }

-

         #region Validation

 

         /// <summary>

@@ -201,17 +197,16 @@
         /// <summary>

         /// Attempt to peek at the next field tag.

         /// </summary>

-        public bool PeekNextTag(out uint fieldTag, out string fieldName)

+        public bool PeekNextTag(out uint fieldTag)

         {

             if (hasNextTag)

             {

-                fieldName = null;

                 fieldTag = nextTag;

                 return true;

             }

 

             uint savedLast = lastTag;

-            hasNextTag = ReadTag(out nextTag, out fieldName);

+            hasNextTag = ReadTag(out nextTag);

             lastTag = savedLast;

             fieldTag = nextTag;

             return hasNextTag;

@@ -222,12 +217,9 @@
         /// of the input data.

         /// </summary>

         /// <param name="fieldTag">The 'tag' of the field (id * 8 + wire-format)</param>

-        /// <param name="fieldName">Not Supported - For protobuffer streams, this parameter is always null</param>

         /// <returns>true if the next fieldTag was read</returns>

-        public bool ReadTag(out uint fieldTag, out string fieldName)

+        public bool ReadTag(out uint fieldTag)

         {

-            fieldName = null;

-

             if (hasNextTag)

             {

                 fieldTag = nextTag;

@@ -256,21 +248,21 @@
         /// <summary>

         /// Read a double field from the stream.

         /// </summary>

-        public bool ReadDouble(ref double value)

+        public double ReadDouble()

         {

-            value = FrameworkPortability.Int64ToDouble((long) ReadRawLittleEndian64());

-            return true;

+            return FrameworkPortability.Int64ToDouble((long) ReadRawLittleEndian64());

         }

 

         /// <summary>

         /// Read a float field from the stream.

         /// </summary>

-        public bool ReadFloat(ref float value)

+        public float ReadFloat()

         {

             if (BitConverter.IsLittleEndian && 4 <= bufferSize - bufferPos)

             {

-                value = BitConverter.ToSingle(buffer, bufferPos);

+                float ret = BitConverter.ToSingle(buffer, bufferPos);

                 bufferPos += 4;

+                return ret;

             }

             else

             {

@@ -279,76 +271,68 @@
                 {

                     ByteArray.Reverse(rawBytes);

                 }

-                value = BitConverter.ToSingle(rawBytes, 0);

+                return BitConverter.ToSingle(rawBytes, 0);

             }

-            return true;

         }

 

         /// <summary>

         /// Read a uint64 field from the stream.

         /// </summary>

-        public bool ReadUInt64(ref ulong value)

+        public ulong ReadUInt64()

         {

-            value = ReadRawVarint64();

-            return true;

+            return ReadRawVarint64();

         }

 

         /// <summary>

         /// Read an int64 field from the stream.

         /// </summary>

-        public bool ReadInt64(ref long value)

+        public long ReadInt64()

         {

-            value = (long) ReadRawVarint64();

-            return true;

+            return (long) ReadRawVarint64();

         }

 

         /// <summary>

         /// Read an int32 field from the stream.

         /// </summary>

-        public bool ReadInt32(ref int value)

+        public int ReadInt32()

         {

-            value = (int) ReadRawVarint32();

-            return true;

+            return (int) ReadRawVarint32();

         }

 

         /// <summary>

         /// Read a fixed64 field from the stream.

         /// </summary>

-        public bool ReadFixed64(ref ulong value)

+        public ulong ReadFixed64()

         {

-            value = ReadRawLittleEndian64();

-            return true;

+            return ReadRawLittleEndian64();

         }

 

         /// <summary>

         /// Read a fixed32 field from the stream.

         /// </summary>

-        public bool ReadFixed32(ref uint value)

+        public uint ReadFixed32()

         {

-            value = ReadRawLittleEndian32();

-            return true;

+            return ReadRawLittleEndian32();

         }

 

         /// <summary>

         /// Read a bool field from the stream.

         /// </summary>

-        public bool ReadBool(ref bool value)

+        public bool ReadBool()

         {

-            value = ReadRawVarint32() != 0;

-            return true;

+            return ReadRawVarint32() != 0;

         }

 

         /// <summary>

         /// Reads a string field from the stream.

         /// </summary>

-        public bool ReadString(ref string value)

+        public string ReadString()

         {

             int size = (int) ReadRawVarint32();

             // No need to read any data for an empty string.

             if (size == 0)

             {

-                value = "";

-                return true;

+                return "";

             }

             if (size <= bufferSize - bufferPos)

             {

@@ -356,12 +340,10 @@
                 //   just copy directly from it.

                 String result = Encoding.UTF8.GetString(buffer, bufferPos, size);

                 bufferPos += size;

-                value = result;

-                return true;

+                return result;

             }

             // Slow path: Build a byte array first then copy it.

-            value = Encoding.UTF8.GetString(ReadRawBytes(size), 0, size);

-            return true;

+            return Encoding.UTF8.GetString(ReadRawBytes(size), 0, size);

         }

 

         /// <summary>

@@ -400,7 +382,7 @@
         /// <summary>

         /// Reads a bytes field value from the stream.

         /// </summary>   

-        public bool ReadBytes(ref ByteString value)

+        public ByteString ReadBytes()

         {

             int size = (int) ReadRawVarint32();

             if (size <= bufferSize - bufferPos && size > 0)

@@ -409,24 +391,21 @@
                 //   just copy directly from it.

                 ByteString result = ByteString.CopyFrom(buffer, bufferPos, size);

                 bufferPos += size;

-                value = result;

-                return true;

+                return result;

             }

             else

             {

                 // Slow path:  Build a byte array and attach it to a new ByteString.

-                value = ByteString.AttachBytes(ReadRawBytes(size));

-                return true;

+                return ByteString.AttachBytes(ReadRawBytes(size));

             }

         }

 

         /// <summary>

         /// Reads a uint32 field value from the stream.

         /// </summary>   

-        public bool ReadUInt32(ref uint value)

+        public uint ReadUInt32()

         {

-            value = ReadRawVarint32();

-            return true;

+            return ReadRawVarint32();

         }

 

         /// <summary>

@@ -434,47 +413,42 @@
         /// then the ref value is set and it returns true.  Otherwise the unknown output

         /// value is set and this method returns false.

         /// </summary>   

-        public bool ReadEnum(ref int value)

+        public int ReadEnum()

         {

             // Currently just a pass-through, but it's nice to separate it logically from WriteInt32.

-            value = (int) ReadRawVarint32();

-            return true;

+            return (int) ReadRawVarint32();

         }

 

         /// <summary>

         /// Reads an sfixed32 field value from the stream.

         /// </summary>   

-        public bool ReadSFixed32(ref int value)

+        public int ReadSFixed32()

         {

-            value = (int) ReadRawLittleEndian32();

-            return true;

+            return (int) ReadRawLittleEndian32();

         }

 

         /// <summary>

         /// Reads an sfixed64 field value from the stream.

         /// </summary>   

-        public bool ReadSFixed64(ref long value)

+        public long ReadSFixed64()

         {

-            value = (long) ReadRawLittleEndian64();

-            return true;

+            return (long) ReadRawLittleEndian64();

         }

 

         /// <summary>

         /// Reads an sint32 field value from the stream.

         /// </summary>   

-        public bool ReadSInt32(ref int value)

+        public int ReadSInt32()

         {

-            value = DecodeZigZag32(ReadRawVarint32());

-            return true;

+            return DecodeZigZag32(ReadRawVarint32());

         }

 

         /// <summary>

         /// Reads an sint64 field value from the stream.

         /// </summary>   

-        public bool ReadSInt64(ref long value)

+        public long ReadSInt64()

         {

-            value = DecodeZigZag64(ReadRawVarint64());

-            return true;

+            return DecodeZigZag64(ReadRawVarint64());

         }

 

         private bool BeginArray(uint fieldTag, out bool isPacked, out int oldLimit)

@@ -502,9 +476,8 @@
         /// </summary>

         private bool ContinueArray(uint currentTag)

         {

-            string ignore;

             uint next;

-            if (PeekNextTag(out next, out ignore))

+            if (PeekNextTag(out next))

             {

                 if (next == currentTag)

                 {

@@ -530,9 +503,8 @@
                 return true;

             }

 

-            string ignore;

             uint next;

-            if (PeekNextTag(out next, out ignore))

+            if (PeekNextTag(out next))

             {

                 if (next == currentTag)

                 {

@@ -543,259 +515,194 @@
             return false;

         }

 

-        public void ReadPrimitiveArray(FieldType fieldType, uint fieldTag, string fieldName, ICollection<object> list)

+        public void ReadStringArray(uint fieldTag, ICollection<string> list)

         {

-            WireFormat.WireType normal = WireFormat.GetWireType(fieldType);

-            WireFormat.WireType wformat = WireFormat.GetTagWireType(fieldTag);

-

-            // 2.3 allows packed form even if the field is not declared packed.

-            if (normal != wformat && wformat == WireFormat.WireType.LengthDelimited)

-            {

-                int length = (int) (ReadRawVarint32() & int.MaxValue);

-                int limit = PushLimit(length);

-                while (!ReachedLimit)

-                {

-                    Object value = null;

-                    if (ReadPrimitiveField(fieldType, ref value))

-                    {

-                        list.Add(value);

-                    }

-                }

-                PopLimit(limit);

-            }

-            else

-            {

-                Object value = null;

-                do

-                {

-                    if (ReadPrimitiveField(fieldType, ref value))

-                    {

-                        list.Add(value);

-                    }

-                } while (ContinueArray(fieldTag));

-            }

-        }

-

-        public void ReadStringArray(uint fieldTag, string fieldName, ICollection<string> list)

-        {

-            string tmp = null;

             do

             {

-                ReadString(ref tmp);

-                list.Add(tmp);

+                list.Add(ReadString());

             } while (ContinueArray(fieldTag));

         }

 

-        public void ReadBytesArray(uint fieldTag, string fieldName, ICollection<ByteString> list)

+        public void ReadBytesArray(uint fieldTag, ICollection<ByteString> list)

         {

-            ByteString tmp = null;

             do

             {

-                ReadBytes(ref tmp);

-                list.Add(tmp);

+                list.Add(ReadBytes());

             } while (ContinueArray(fieldTag));

         }

 

-        public void ReadBoolArray(uint fieldTag, string fieldName, ICollection<bool> list)

+        public void ReadBoolArray(uint fieldTag, ICollection<bool> list)

         {

             bool isPacked;

             int holdLimit;

             if (BeginArray(fieldTag, out isPacked, out holdLimit))

             {

-                bool tmp = false;

                 do

                 {

-                    ReadBool(ref tmp);

-                    list.Add(tmp);

+                    list.Add(ReadBool());

                 } while (ContinueArray(fieldTag, isPacked, holdLimit));

             }

         }

 

-        public void ReadInt32Array(uint fieldTag, string fieldName, ICollection<int> list)

-        {

-            // TODO(jonskeet): Work out how this works for non-packed values. (It doesn't look like it does...)

-            bool isPacked;

-            int holdLimit;

-            if (BeginArray(fieldTag, out isPacked, out holdLimit))

-            {

-                int tmp = 0;

-                do

-                {

-                    ReadInt32(ref tmp);

-                    list.Add(tmp);

-                } while (ContinueArray(fieldTag, isPacked, holdLimit));

-            }

-        }

-

-        public void ReadSInt32Array(uint fieldTag, string fieldName, ICollection<int> list)

+        public void ReadInt32Array(uint fieldTag, ICollection<int> list)

         {

             bool isPacked;

             int holdLimit;

             if (BeginArray(fieldTag, out isPacked, out holdLimit))

             {

-                int tmp = 0;

                 do

                 {

-                    ReadSInt32(ref tmp);

-                    list.Add(tmp);

+                    list.Add(ReadInt32());

                 } while (ContinueArray(fieldTag, isPacked, holdLimit));

             }

         }

 

-        public void ReadUInt32Array(uint fieldTag, string fieldName, ICollection<uint> list)

+        public void ReadSInt32Array(uint fieldTag, ICollection<int> list)

         {

             bool isPacked;

             int holdLimit;

             if (BeginArray(fieldTag, out isPacked, out holdLimit))

             {

-                uint tmp = 0;

                 do

                 {

-                    ReadUInt32(ref tmp);

-                    list.Add(tmp);

+                    list.Add(ReadSInt32());

                 } while (ContinueArray(fieldTag, isPacked, holdLimit));

             }

         }

 

-        public void ReadFixed32Array(uint fieldTag, string fieldName, ICollection<uint> list)

+        public void ReadUInt32Array(uint fieldTag, ICollection<uint> list)

         {

             bool isPacked;

             int holdLimit;

             if (BeginArray(fieldTag, out isPacked, out holdLimit))

             {

-                uint tmp = 0;

                 do

                 {

-                    ReadFixed32(ref tmp);

-                    list.Add(tmp);

+                    list.Add(ReadUInt32());

                 } while (ContinueArray(fieldTag, isPacked, holdLimit));

             }

         }

 

-        public void ReadSFixed32Array(uint fieldTag, string fieldName, ICollection<int> list)

+        public void ReadFixed32Array(uint fieldTag, ICollection<uint> list)

         {

             bool isPacked;

             int holdLimit;

             if (BeginArray(fieldTag, out isPacked, out holdLimit))

             {

-                int tmp = 0;

                 do

                 {

-                    ReadSFixed32(ref tmp);

-                    list.Add(tmp);

+                    list.Add(ReadFixed32());

                 } while (ContinueArray(fieldTag, isPacked, holdLimit));

             }

         }

 

-        public void ReadInt64Array(uint fieldTag, string fieldName, ICollection<long> list)

+        public void ReadSFixed32Array(uint fieldTag, ICollection<int> list)

         {

             bool isPacked;

             int holdLimit;

             if (BeginArray(fieldTag, out isPacked, out holdLimit))

             {

-                long tmp = 0;

                 do

                 {

-                    ReadInt64(ref tmp);

-                    list.Add(tmp);

+                    list.Add(ReadSFixed32());

                 } while (ContinueArray(fieldTag, isPacked, holdLimit));

             }

         }

 

-        public void ReadSInt64Array(uint fieldTag, string fieldName, ICollection<long> list)

+        public void ReadInt64Array(uint fieldTag, ICollection<long> list)

         {

             bool isPacked;

             int holdLimit;

             if (BeginArray(fieldTag, out isPacked, out holdLimit))

             {

-                long tmp = 0;

                 do

                 {

-                    ReadSInt64(ref tmp);

-                    list.Add(tmp);

+                    list.Add(ReadInt64());

                 } while (ContinueArray(fieldTag, isPacked, holdLimit));

             }

         }

 

-        public void ReadUInt64Array(uint fieldTag, string fieldName, ICollection<ulong> list)

+        public void ReadSInt64Array(uint fieldTag, ICollection<long> list)

         {

             bool isPacked;

             int holdLimit;

             if (BeginArray(fieldTag, out isPacked, out holdLimit))

             {

-                ulong tmp = 0;

                 do

                 {

-                    ReadUInt64(ref tmp);

-                    list.Add(tmp);

+                    list.Add(ReadSInt64());

                 } while (ContinueArray(fieldTag, isPacked, holdLimit));

             }

         }

 

-        public void ReadFixed64Array(uint fieldTag, string fieldName, ICollection<ulong> list)

+        public void ReadUInt64Array(uint fieldTag, ICollection<ulong> list)

         {

             bool isPacked;

             int holdLimit;

             if (BeginArray(fieldTag, out isPacked, out holdLimit))

             {

-                ulong tmp = 0;

                 do

                 {

-                    ReadFixed64(ref tmp);

-                    list.Add(tmp);

+                    list.Add(ReadUInt64());

                 } while (ContinueArray(fieldTag, isPacked, holdLimit));

             }

         }

 

-        public void ReadSFixed64Array(uint fieldTag, string fieldName, ICollection<long> list)

+        public void ReadFixed64Array(uint fieldTag, ICollection<ulong> list)

         {

             bool isPacked;

             int holdLimit;

             if (BeginArray(fieldTag, out isPacked, out holdLimit))

             {

-                long tmp = 0;

                 do

                 {

-                    ReadSFixed64(ref tmp);

-                    list.Add(tmp);

+                    list.Add(ReadFixed64());

                 } while (ContinueArray(fieldTag, isPacked, holdLimit));

             }

         }

 

-        public void ReadDoubleArray(uint fieldTag, string fieldName, ICollection<double> list)

+        public void ReadSFixed64Array(uint fieldTag, ICollection<long> list)

         {

             bool isPacked;

             int holdLimit;

             if (BeginArray(fieldTag, out isPacked, out holdLimit))

             {

-                double tmp = 0;

                 do

                 {

-                    ReadDouble(ref tmp);

-                    list.Add(tmp);

+                    list.Add(ReadSFixed64());

                 } while (ContinueArray(fieldTag, isPacked, holdLimit));

             }

         }

 

-        public void ReadFloatArray(uint fieldTag, string fieldName, ICollection<float> list)

+        public void ReadDoubleArray(uint fieldTag, ICollection<double> list)

         {

             bool isPacked;

             int holdLimit;

             if (BeginArray(fieldTag, out isPacked, out holdLimit))

             {

-                float tmp = 0;

                 do

                 {

-                    ReadFloat(ref tmp);

-                    list.Add(tmp);

+                    list.Add(ReadDouble());

                 } while (ContinueArray(fieldTag, isPacked, holdLimit));

             }

         }

 

-        public void ReadEnumArray<T>(uint fieldTag, string fieldName, ICollection<T> list)

+        public void ReadFloatArray(uint fieldTag, ICollection<float> list)

+        {

+            bool isPacked;

+            int holdLimit;

+            if (BeginArray(fieldTag, out isPacked, out holdLimit))

+            {

+                do

+                {

+                    list.Add(ReadFloat());

+                } while (ContinueArray(fieldTag, isPacked, holdLimit));

+            }

+        }

+

+        public void ReadEnumArray<T>(uint fieldTag, ICollection<T> list)

             where T : struct, IComparable, IFormattable

         {

-            int value = 0;

             WireFormat.WireType wformat = WireFormat.GetTagWireType(fieldTag);

 

             // 2.3 allows packed form even if the field is not declared packed.

@@ -805,9 +712,8 @@
                 int limit = PushLimit(length);

                 while (!ReachedLimit)

                 {

-                    ReadEnum(ref value);

                     // TODO(jonskeet): Avoid this horrible boxing!

-                    list.Add((T)(object)value);

+                    list.Add((T)(object) ReadEnum());

                 }

                 PopLimit(limit);

             }

@@ -815,14 +721,12 @@
             {

                 do

                 {

-                    ReadEnum(ref value);

-                    // TODO(jonskeet): Avoid this horrible boxing!

-                    list.Add((T)(object) value);

+                    list.Add((T)(object) ReadEnum());

                 } while (ContinueArray(fieldTag));

             }

         }

 

-        public void ReadMessageArray<T>(uint fieldTag, string fieldName, ICollection<T> list, MessageParser<T> messageParser)

+        public void ReadMessageArray<T>(uint fieldTag, ICollection<T> list, MessageParser<T> messageParser)

             where T : IMessage<T>

         {

             do

@@ -833,7 +737,7 @@
             } while (ContinueArray(fieldTag));

         }

 

-        public void ReadGroupArray<T>(uint fieldTag, string fieldName, ICollection<T> list, MessageParser<T> messageParser)

+        public void ReadGroupArray<T>(uint fieldTag, ICollection<T> list, MessageParser<T> messageParser)

             where T : IMessage<T>

         {

             do

@@ -843,178 +747,6 @@
                 list.Add(message);

             } while (ContinueArray(fieldTag));

         }

-

-        /// <summary>

-        /// Reads a field of any primitive type. Enums, groups and embedded

-        /// messages are not handled by this method.

-        /// </summary>

-        public bool ReadPrimitiveField(FieldType fieldType, ref object value)

-        {

-            switch (fieldType)

-            {

-                case FieldType.Double:

-                    {

-                        double tmp = 0;

-                        if (ReadDouble(ref tmp))

-                        {

-                            value = tmp;

-                            return true;

-                        }

-                        return false;

-                    }

-                case FieldType.Float:

-                    {

-                        float tmp = 0;

-                        if (ReadFloat(ref tmp))

-                        {

-                            value = tmp;

-                            return true;

-                        }

-                        return false;

-                    }

-                case FieldType.Int64:

-                    {

-                        long tmp = 0;

-                        if (ReadInt64(ref tmp))

-                        {

-                            value = tmp;

-                            return true;

-                        }

-                        return false;

-                    }

-                case FieldType.UInt64:

-                    {

-                        ulong tmp = 0;

-                        if (ReadUInt64(ref tmp))

-                        {

-                            value = tmp;

-                            return true;

-                        }

-                        return false;

-                    }

-                case FieldType.Int32:

-                    {

-                        int tmp = 0;

-                        if (ReadInt32(ref tmp))

-                        {

-                            value = tmp;

-                            return true;

-                        }

-                        return false;

-                    }

-                case FieldType.Fixed64:

-                    {

-                        ulong tmp = 0;

-                        if (ReadFixed64(ref tmp))

-                        {

-                            value = tmp;

-                            return true;

-                        }

-                        return false;

-                    }

-                case FieldType.Fixed32:

-                    {

-                        uint tmp = 0;

-                        if (ReadFixed32(ref tmp))

-                        {

-                            value = tmp;

-                            return true;

-                        }

-                        return false;

-                    }

-                case FieldType.Bool:

-                    {

-                        bool tmp = false;

-                        if (ReadBool(ref tmp))

-                        {

-                            value = tmp;

-                            return true;

-                        }

-                        return false;

-                    }

-                case FieldType.String:

-                    {

-                        string tmp = null;

-                        if (ReadString(ref tmp))

-                        {

-                            value = tmp;

-                            return true;

-                        }

-                        return false;

-                    }

-                case FieldType.Bytes:

-                    {

-                        ByteString tmp = null;

-                        if (ReadBytes(ref tmp))

-                        {

-                            value = tmp;

-                            return true;

-                        }

-                        return false;

-                    }

-                case FieldType.UInt32:

-                    {

-                        uint tmp = 0;

-                        if (ReadUInt32(ref tmp))

-                        {

-                            value = tmp;

-                            return true;

-                        }

-                        return false;

-                    }

-                case FieldType.SFixed32:

-                    {

-                        int tmp = 0;

-                        if (ReadSFixed32(ref tmp))

-                        {

-                            value = tmp;

-                            return true;

-                        }

-                        return false;

-                    }

-                case FieldType.SFixed64:

-                    {

-                        long tmp = 0;

-                        if (ReadSFixed64(ref tmp))

-                        {

-                            value = tmp;

-                            return true;

-                        }

-                        return false;

-                    }

-                case FieldType.SInt32:

-                    {

-                        int tmp = 0;

-                        if (ReadSInt32(ref tmp))

-                        {

-                            value = tmp;

-                            return true;

-                        }

-                        return false;

-                    }

-                case FieldType.SInt64:

-                    {

-                        long tmp = 0;

-                        if (ReadSInt64(ref tmp))

-                        {

-                            value = tmp;

-                            return true;

-                        }

-                        return false;

-                    }

-                case FieldType.Group:

-                    throw new ArgumentException("ReadPrimitiveField() cannot handle nested groups.");

-                case FieldType.Message:

-                    throw new ArgumentException("ReadPrimitiveField() cannot handle embedded messages.");

-                    // We don't handle enums because we don't know what to do if the

-                    // value is not recognized.

-                case FieldType.Enum:

-                    throw new ArgumentException("ReadPrimitiveField() cannot handle enums.");

-                default:

-                    throw new ArgumentOutOfRangeException("Invalid field type " + fieldType);

-            }

-        }

-

         #endregion

 

         #region Underlying reading primitives

@@ -1622,8 +1354,7 @@
         public void SkipMessage()

         {

             uint tag;

-            string name;

-            while (ReadTag(out tag, out name))

+            while (ReadTag(out tag))

             {

                 if (!SkipField())

                 {

diff --git a/csharp/src/ProtocolBuffers/CodedOutputStream.ComputeSize.cs b/csharp/src/ProtocolBuffers/CodedOutputStream.ComputeSize.cs
index 96be9db..b7629d7 100644
--- a/csharp/src/ProtocolBuffers/CodedOutputStream.ComputeSize.cs
+++ b/csharp/src/ProtocolBuffers/CodedOutputStream.ComputeSize.cs
@@ -413,41 +413,12 @@
             return ComputeRawVarint64Size(EncodeZigZag64(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.

-     */

-

-        /// <summary>

-        /// 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.

-        /// </summary>

-        public static int ComputeMessageSetExtensionSize(int fieldNumber, IMessage value)

-        {

-            return ComputeTagSize(WireFormat.MessageSetField.Item)*2 +

-                   ComputeUInt32Size(WireFormat.MessageSetField.TypeID, (uint) fieldNumber) +

-                   ComputeMessageSize(WireFormat.MessageSetField.Message, value);

-        }

-

-        /// <summary>

-        /// 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.

-        /// </summary>

-        public static int ComputeRawMessageSetExtensionSize(int fieldNumber, ByteString value)

-        {

-            return ComputeTagSize(WireFormat.MessageSetField.Item)*2 +

-                   ComputeUInt32Size(WireFormat.MessageSetField.TypeID, (uint) fieldNumber) +

-                   ComputeBytesSize(WireFormat.MessageSetField.Message, value);

-        }

-

         /// <summary>

         /// Compute the number of bytes that would be needed to encode a varint.

         /// </summary>

         public static int ComputeRawVarint32Size(uint value)

         {

+            // TODO(jonskeet): Look at optimizing this to just hard-coded comparisons.

             if ((value & (0xffffffff << 7)) == 0)

             {

                 return 1;

@@ -472,6 +443,7 @@
         /// </summary>

         public static int ComputeRawVarint64Size(ulong value)

         {

+            // TODO(jonskeet): Look at optimizing this to just hard-coded comparisons.

             if ((value & (0xffffffffffffffffL << 7)) == 0)

             {

                 return 1;

@@ -512,106 +484,6 @@
         }

 

         /// <summary>

-        /// Compute the number of bytes that would be needed to encode a

-        /// field of arbitrary type, including the tag, to the stream.

-        /// </summary>

-        // TODO(jonskeet): Why do we need this?

-        public static int ComputeFieldSize(FieldType fieldType, int fieldNumber, Object value)

-        {

-            switch (fieldType)

-            {

-                case FieldType.Double:

-                    return ComputeDoubleSize(fieldNumber, (double) value);

-                case FieldType.Float:

-                    return ComputeFloatSize(fieldNumber, (float) value);

-                case FieldType.Int64:

-                    return ComputeInt64Size(fieldNumber, (long) value);

-                case FieldType.UInt64:

-                    return ComputeUInt64Size(fieldNumber, (ulong) value);

-                case FieldType.Int32:

-                    return ComputeInt32Size(fieldNumber, (int) value);

-                case FieldType.Fixed64:

-                    return ComputeFixed64Size(fieldNumber, (ulong) value);

-                case FieldType.Fixed32:

-                    return ComputeFixed32Size(fieldNumber, (uint) value);

-                case FieldType.Bool:

-                    return ComputeBoolSize(fieldNumber, (bool) value);

-                case FieldType.String:

-                    return ComputeStringSize(fieldNumber, (string) value);

-                case FieldType.Group:

-                    return ComputeGroupSize(fieldNumber, (IMessage) value);

-                case FieldType.Message:

-                    return ComputeMessageSize(fieldNumber, (IMessage) value);

-                case FieldType.Bytes:

-                    return ComputeBytesSize(fieldNumber, (ByteString) value);

-                case FieldType.UInt32:

-                    return ComputeUInt32Size(fieldNumber, (uint) value);

-                case FieldType.SFixed32:

-                    return ComputeSFixed32Size(fieldNumber, (int) value);

-                case FieldType.SFixed64:

-                    return ComputeSFixed64Size(fieldNumber, (long) value);

-                case FieldType.SInt32:

-                    return ComputeSInt32Size(fieldNumber, (int) value);

-                case FieldType.SInt64:

-                    return ComputeSInt64Size(fieldNumber, (long) value);

-                case FieldType.Enum:

-                    return ComputeEnumSize(fieldNumber, (int) value);

-                default:

-                    throw new ArgumentOutOfRangeException("Invalid field type " + fieldType);

-            }

-        }

-

-        /// <summary>

-        /// Compute the number of bytes that would be needed to encode a

-        /// field of arbitrary type, excluding the tag, to the stream.

-        /// </summary>

-        // TODO(jonskeet): Why do we need this?

-        public static int ComputeFieldSizeNoTag(FieldType fieldType, Object value)

-        {

-            switch (fieldType)

-            {

-                case FieldType.Double:

-                    return ComputeDoubleSizeNoTag((double) value);

-                case FieldType.Float:

-                    return ComputeFloatSizeNoTag((float) value);

-                case FieldType.Int64:

-                    return ComputeInt64SizeNoTag((long) value);

-                case FieldType.UInt64:

-                    return ComputeUInt64SizeNoTag((ulong) value);

-                case FieldType.Int32:

-                    return ComputeInt32SizeNoTag((int) value);

-                case FieldType.Fixed64:

-                    return ComputeFixed64SizeNoTag((ulong) value);

-                case FieldType.Fixed32:

-                    return ComputeFixed32SizeNoTag((uint) value);

-                case FieldType.Bool:

-                    return ComputeBoolSizeNoTag((bool) value);

-                case FieldType.String:

-                    return ComputeStringSizeNoTag((string) value);

-                case FieldType.Group:

-                    return ComputeGroupSizeNoTag((IMessage) value);

-                case FieldType.Message:

-                    return ComputeMessageSizeNoTag((IMessage) value);

-                case FieldType.Bytes:

-                    return ComputeBytesSizeNoTag((ByteString) value);

-                case FieldType.UInt32:

-                    return ComputeUInt32SizeNoTag((uint) value);

-                case FieldType.SFixed32:

-                    return ComputeSFixed32SizeNoTag((int) value);

-                case FieldType.SFixed64:

-                    return ComputeSFixed64SizeNoTag((long) value);

-                case FieldType.SInt32:

-                    return ComputeSInt32SizeNoTag((int) value);

-                case FieldType.SInt64:

-                    return ComputeSInt64SizeNoTag((long) value);

-                case FieldType.Enum:

-                    return ComputeEnumSizeNoTag((int) value);

-                default:

-                    throw new ArgumentOutOfRangeException("Invalid field type " + fieldType);

-            }

-        }

-

-        /// <summary>

         /// Compute the number of bytes that would be needed to encode a tag.

         /// </summary>

         public static int ComputeTagSize(int fieldNumber)

diff --git a/csharp/src/ProtocolBuffers/CodedOutputStream.cs b/csharp/src/ProtocolBuffers/CodedOutputStream.cs
index e3f0c70..132f806 100644
--- a/csharp/src/ProtocolBuffers/CodedOutputStream.cs
+++ b/csharp/src/ProtocolBuffers/CodedOutputStream.cs
@@ -57,7 +57,7 @@
     /// methods are taken from the protocol buffer type names, not .NET types.

     /// (Hence WriteFloat instead of WriteSingle, and WriteBool instead of WriteBoolean.)

     /// </remarks>

-    public sealed partial class CodedOutputStream : ICodedOutputStream

+    public sealed partial class CodedOutputStream

     {

         private static readonly Encoding UTF8 = Encoding.UTF8;

 

@@ -143,76 +143,11 @@
             }

         }

 

-        void ICodedOutputStream.WriteMessageStart() { }

-        void ICodedOutputStream.WriteMessageEnd() { Flush(); }

-

         #region Writing of tags and fields

-

-        // TODO(jonskeet): Do we need this?

-        public void WriteField(FieldType fieldType, int fieldNumber, string fieldName, object value)

-        {

-            switch (fieldType)

-            {

-                case FieldType.String:

-                    WriteString(fieldNumber, fieldName, (string) value);

-                    break;

-                case FieldType.Message:

-                    WriteMessage(fieldNumber, fieldName, (IMessage) value);

-                    break;

-                case FieldType.Group:

-                    WriteGroup(fieldNumber, fieldName, (IMessage) value);

-                    break;

-                case FieldType.Bytes:

-                    WriteBytes(fieldNumber, fieldName, (ByteString) value);

-                    break;

-                case FieldType.Bool:

-                    WriteBool(fieldNumber, fieldName, (bool) value);

-                    break;

-                case FieldType.Enum:

-                    throw new NotImplementedException();

-                case FieldType.Int32:

-                    WriteInt32(fieldNumber, fieldName, (int) value);

-                    break;

-                case FieldType.Int64:

-                    WriteInt64(fieldNumber, fieldName, (long) value);

-                    break;

-                case FieldType.UInt32:

-                    WriteUInt32(fieldNumber, fieldName, (uint) value);

-                    break;

-                case FieldType.UInt64:

-                    WriteUInt64(fieldNumber, fieldName, (ulong) value);

-                    break;

-                case FieldType.SInt32:

-                    WriteSInt32(fieldNumber, fieldName, (int) value);

-                    break;

-                case FieldType.SInt64:

-                    WriteSInt64(fieldNumber, fieldName, (long) value);

-                    break;

-                case FieldType.Fixed32:

-                    WriteFixed32(fieldNumber, fieldName, (uint) value);

-                    break;

-                case FieldType.Fixed64:

-                    WriteFixed64(fieldNumber, fieldName, (ulong) value);

-                    break;

-                case FieldType.SFixed32:

-                    WriteSFixed32(fieldNumber, fieldName, (int) value);

-                    break;

-                case FieldType.SFixed64:

-                    WriteSFixed64(fieldNumber, fieldName, (long) value);

-                    break;

-                case FieldType.Double:

-                    WriteDouble(fieldNumber, fieldName, (double) value);

-                    break;

-                case FieldType.Float:

-                    WriteFloat(fieldNumber, fieldName, (float) value);

-                    break;

-            }

-        }

-

         /// <summary>

         /// Writes a double field value, including tag, to the stream.

         /// </summary>

-        public void WriteDouble(int fieldNumber, string fieldName, double value)

+        public void WriteDouble(int fieldNumber, double value)

         {

             WriteTag(fieldNumber, WireFormat.WireType.Fixed64);

             WriteDoubleNoTag(value);

@@ -221,7 +156,7 @@
         /// <summary>

         /// Writes a float field value, including tag, to the stream.

         /// </summary>

-        public void WriteFloat(int fieldNumber, string fieldName, float value)

+        public void WriteFloat(int fieldNumber, float value)

         {

             WriteTag(fieldNumber, WireFormat.WireType.Fixed32);

             WriteFloatNoTag(value);

@@ -230,7 +165,7 @@
         /// <summary>

         /// Writes a uint64 field value, including tag, to the stream.

         /// </summary>

-        public void WriteUInt64(int fieldNumber, string fieldName, ulong value)

+        public void WriteUInt64(int fieldNumber, ulong value)

         {

             WriteTag(fieldNumber, WireFormat.WireType.Varint);

             WriteRawVarint64(value);

@@ -239,7 +174,7 @@
         /// <summary>

         /// Writes an int64 field value, including tag, to the stream.

         /// </summary>

-        public void WriteInt64(int fieldNumber, string fieldName, long value)

+        public void WriteInt64(int fieldNumber, long value)

         {

             WriteTag(fieldNumber, WireFormat.WireType.Varint);

             WriteRawVarint64((ulong) value);

@@ -248,7 +183,7 @@
         /// <summary>

         /// Writes an int32 field value, including tag, to the stream.

         /// </summary>

-        public void WriteInt32(int fieldNumber, string fieldName, int value)

+        public void WriteInt32(int fieldNumber, int value)

         {

             WriteTag(fieldNumber, WireFormat.WireType.Varint);

             if (value >= 0)

@@ -265,7 +200,7 @@
         /// <summary>

         /// Writes a fixed64 field value, including tag, to the stream.

         /// </summary>

-        public void WriteFixed64(int fieldNumber, string fieldName, ulong value)

+        public void WriteFixed64(int fieldNumber, ulong value)

         {

             WriteTag(fieldNumber, WireFormat.WireType.Fixed64);

             WriteRawLittleEndian64(value);

@@ -274,7 +209,7 @@
         /// <summary>

         /// Writes a fixed32 field value, including tag, to the stream.

         /// </summary>

-        public void WriteFixed32(int fieldNumber, string fieldName, uint value)

+        public void WriteFixed32(int fieldNumber, uint value)

         {

             WriteTag(fieldNumber, WireFormat.WireType.Fixed32);

             WriteRawLittleEndian32(value);

@@ -283,7 +218,7 @@
         /// <summary>

         /// Writes a bool field value, including tag, to the stream.

         /// </summary>

-        public void WriteBool(int fieldNumber, string fieldName, bool value)

+        public void WriteBool(int fieldNumber, bool value)

         {

             WriteTag(fieldNumber, WireFormat.WireType.Varint);

             WriteRawByte(value ? (byte) 1 : (byte) 0);

@@ -292,7 +227,7 @@
         /// <summary>

         /// Writes a string field value, including tag, to the stream.

         /// </summary>

-        public void WriteString(int fieldNumber, string fieldName, string value)

+        public void WriteString(int fieldNumber, string value)

         {

             WriteTag(fieldNumber, WireFormat.WireType.LengthDelimited);

             // Optimise the case where we have enough space to write

@@ -324,80 +259,63 @@
         /// <summary>

         /// Writes a group field value, including tag, to the stream.

         /// </summary>

-        public void WriteGroup(int fieldNumber, string fieldName, IMessage value)

+        public void WriteGroup(int fieldNumber, IMessage value)

         {

             WriteTag(fieldNumber, WireFormat.WireType.StartGroup);

             value.WriteTo(this);

             WriteTag(fieldNumber, WireFormat.WireType.EndGroup);

         }

 

-        public void WriteMessage(int fieldNumber, string fieldName, IMessage value)

+        public void WriteMessage(int fieldNumber, IMessage value)

         {

             WriteTag(fieldNumber, WireFormat.WireType.LengthDelimited);

             WriteRawVarint32((uint) value.CalculateSize());

             value.WriteTo(this);

         }

 

-        public void WriteBytes(int fieldNumber, string fieldName, ByteString value)

+        public void WriteBytes(int fieldNumber, ByteString value)

         {

             WriteTag(fieldNumber, WireFormat.WireType.LengthDelimited);

             WriteRawVarint32((uint) value.Length);

             value.WriteRawBytesTo(this);

         }

 

-        public void WriteUInt32(int fieldNumber, string fieldName, uint value)

+        public void WriteUInt32(int fieldNumber, uint value)

         {

             WriteTag(fieldNumber, WireFormat.WireType.Varint);

             WriteRawVarint32(value);

         }

 

-        public void WriteEnum(int fieldNumber, string fieldName, int value)

+        public void WriteEnum(int fieldNumber, int value)

         {

             // Currently just a pass-through, but it's nice to separate it logically from WriteInt32.

             WriteTag(fieldNumber, WireFormat.WireType.Varint);

             WriteInt32NoTag(value);

         }

 

-        public void WriteSFixed32(int fieldNumber, string fieldName, int value)

+        public void WriteSFixed32(int fieldNumber, int value)

         {

             WriteTag(fieldNumber, WireFormat.WireType.Fixed32);

             WriteRawLittleEndian32((uint) value);

         }

 

-        public void WriteSFixed64(int fieldNumber, string fieldName, long value)

+        public void WriteSFixed64(int fieldNumber, long value)

         {

             WriteTag(fieldNumber, WireFormat.WireType.Fixed64);

             WriteRawLittleEndian64((ulong) value);

         }

 

-        public void WriteSInt32(int fieldNumber, string fieldName, int value)

+        public void WriteSInt32(int fieldNumber, int value)

         {

             WriteTag(fieldNumber, WireFormat.WireType.Varint);

             WriteRawVarint32(EncodeZigZag32(value));

         }

 

-        public void WriteSInt64(int fieldNumber, string fieldName, long value)

+        public void WriteSInt64(int fieldNumber, long value)

         {

             WriteTag(fieldNumber, WireFormat.WireType.Varint);

             WriteRawVarint64(EncodeZigZag64(value));

         }

-

-        public void WriteMessageSetExtension(int fieldNumber, string fieldName, IMessage value)

-        {

-            WriteTag(WireFormat.MessageSetField.Item, WireFormat.WireType.StartGroup);

-            WriteUInt32(WireFormat.MessageSetField.TypeID, "type_id", (uint) fieldNumber);

-            WriteMessage(WireFormat.MessageSetField.Message, "message", value);

-            WriteTag(WireFormat.MessageSetField.Item, WireFormat.WireType.EndGroup);

-        }

-

-        public void WriteMessageSetExtension(int fieldNumber, string fieldName, ByteString value)

-        {

-            WriteTag(WireFormat.MessageSetField.Item, WireFormat.WireType.StartGroup);

-            WriteUInt32(WireFormat.MessageSetField.TypeID, "type_id", (uint) fieldNumber);

-            WriteBytes(WireFormat.MessageSetField.Message, "message", value);

-            WriteTag(WireFormat.MessageSetField.Item, WireFormat.WireType.EndGroup);

-        }

-

         #endregion

 

         #region Writing of values without tags

@@ -625,155 +543,145 @@
         #endregion

 

         #region Write array members

-

-        // TODO(jonskeet): Remove?

-        public void WriteArray(FieldType fieldType, int fieldNumber, string fieldName, IEnumerable list)

-        {

-            foreach (object element in list)

-            {

-                WriteField(fieldType, fieldNumber, fieldName, element);

-            }

-        }

-

-        public void WriteGroupArray<T>(int fieldNumber, string fieldName, RepeatedField<T> list)

+        public void WriteGroupArray<T>(int fieldNumber, RepeatedField<T> list)

             where T : IMessage

         {

             foreach (IMessage value in list)

             {

-                WriteGroup(fieldNumber, fieldName, value);

+                WriteGroup(fieldNumber, value);

             }

         }

 

-        public void WriteMessageArray<T>(int fieldNumber, string fieldName, RepeatedField<T> list)

+        public void WriteMessageArray<T>(int fieldNumber, RepeatedField<T> list)

             where T : IMessage

         {

             foreach (IMessage value in list)

             {

-                WriteMessage(fieldNumber, fieldName, value);

+                WriteMessage(fieldNumber, value);

             }

         }

 

-        public void WriteStringArray(int fieldNumber, string fieldName, RepeatedField<string> list)

+        public void WriteStringArray(int fieldNumber, RepeatedField<string> list)

         {

             foreach (var value in list)

             {

-                WriteString(fieldNumber, fieldName, value);

+                WriteString(fieldNumber, value);

             }

         }

 

-        public void WriteBytesArray(int fieldNumber, string fieldName, RepeatedField<ByteString> list)

+        public void WriteBytesArray(int fieldNumber, RepeatedField<ByteString> list)

         {

             foreach (var value in list)

             {

-                WriteBytes(fieldNumber, fieldName, value);

+                WriteBytes(fieldNumber, value);

             }

         }

 

-        public void WriteBoolArray(int fieldNumber, string fieldName, RepeatedField<bool> list)

+        public void WriteBoolArray(int fieldNumber, RepeatedField<bool> list)

         {

             foreach (var value in list)

             {

-                WriteBool(fieldNumber, fieldName, value);

+                WriteBool(fieldNumber, value);

             }

         }

 

-        public void WriteInt32Array(int fieldNumber, string fieldName, RepeatedField<int> list)

+        public void WriteInt32Array(int fieldNumber, RepeatedField<int> list)

         {

             foreach (var value in list)

             {

-                WriteInt32(fieldNumber, fieldName, value);

+                WriteInt32(fieldNumber, value);

             }

         }

 

-        public void WriteSInt32Array(int fieldNumber, string fieldName, RepeatedField<int> list)

+        public void WriteSInt32Array(int fieldNumber, RepeatedField<int> list)

         {

             foreach (var value in list)

             {

-                WriteSInt32(fieldNumber, fieldName, value);

+                WriteSInt32(fieldNumber, value);

             }

         }

 

-        public void WriteUInt32Array(int fieldNumber, string fieldName, RepeatedField<uint> list)

+        public void WriteUInt32Array(int fieldNumber, RepeatedField<uint> list)

         {

             foreach (var value in list)

             {

-                WriteUInt32(fieldNumber, fieldName, value);

+                WriteUInt32(fieldNumber, value);

             }

         }

 

-        public void WriteFixed32Array(int fieldNumber, string fieldName, RepeatedField<uint> list)

+        public void WriteFixed32Array(int fieldNumber, RepeatedField<uint> list)

         {

             foreach (var value in list)

             {

-                WriteFixed32(fieldNumber, fieldName, value);

+                WriteFixed32(fieldNumber, value);

             }

         }

 

-        public void WriteSFixed32Array(int fieldNumber, string fieldName, RepeatedField<int> list)

+        public void WriteSFixed32Array(int fieldNumber, RepeatedField<int> list)

         {

             foreach (var value in list)

             {

-                WriteSFixed32(fieldNumber, fieldName, value);

+                WriteSFixed32(fieldNumber, value);

             }

         }

 

-        public void WriteInt64Array(int fieldNumber, string fieldName, RepeatedField<long> list)

+        public void WriteInt64Array(int fieldNumber, RepeatedField<long> list)

         {

             foreach (var value in list)

             {

-                WriteInt64(fieldNumber, fieldName, value);

+                WriteInt64(fieldNumber, value);

             }

         }

 

-        public void WriteSInt64Array(int fieldNumber, string fieldName, RepeatedField<long> list)

+        public void WriteSInt64Array(int fieldNumber, RepeatedField<long> list)

         {

             foreach (var value in list)

             {

-                WriteSInt64(fieldNumber, fieldName, value);

+                WriteSInt64(fieldNumber, value);

             }

         }

 

-        public void WriteUInt64Array(int fieldNumber, string fieldName, RepeatedField<ulong> list)

+        public void WriteUInt64Array(int fieldNumber, RepeatedField<ulong> list)

         {

             foreach (var value in list)

             {

-                WriteUInt64(fieldNumber, fieldName, value);

+                WriteUInt64(fieldNumber, value);

             }

         }

 

-        public void WriteFixed64Array(int fieldNumber, string fieldName, RepeatedField<ulong> list)

+        public void WriteFixed64Array(int fieldNumber, RepeatedField<ulong> list)

         {

             foreach (var value in list)

             {

-                WriteFixed64(fieldNumber, fieldName, value);

+                WriteFixed64(fieldNumber, value);

             }

         }

 

-        public void WriteSFixed64Array(int fieldNumber, string fieldName, RepeatedField<long> list)

+        public void WriteSFixed64Array(int fieldNumber, RepeatedField<long> list)

         {

             foreach (var value in list)

             {

-                WriteSFixed64(fieldNumber, fieldName, value);

+                WriteSFixed64(fieldNumber, value);

             }

         }

 

-        public void WriteDoubleArray(int fieldNumber, string fieldName, RepeatedField<double> list)

+        public void WriteDoubleArray(int fieldNumber, RepeatedField<double> list)

         {

             foreach (var value in list)

             {

-                WriteDouble(fieldNumber, fieldName, value);

+                WriteDouble(fieldNumber, value);

             }

         }

 

-        public void WriteFloatArray(int fieldNumber, string fieldName, RepeatedField<float> list)

+        public void WriteFloatArray(int fieldNumber, RepeatedField<float> list)

         {

             foreach (var value in list)

             {

-                WriteFloat(fieldNumber, fieldName, value);

+                WriteFloat(fieldNumber, value);

             }

         }

 

-        public void WriteEnumArray<T>(int fieldNumber, string fieldName, RepeatedField<T> list)

+        public void WriteEnumArray<T>(int fieldNumber, RepeatedField<T> list)

             where T : struct, IComparable, IFormattable

         {

             if (list.Count == 0)

@@ -783,34 +691,15 @@
             // TODO(jonskeet): Avoid the Cast call here. Work out a better mass "T to int" conversion.

             foreach (int value in list.Cast<int>())

             {

-                WriteEnum(fieldNumber, fieldName, value);

+                WriteEnum(fieldNumber, value);

             }

         }

 

         #endregion

 

         #region Write packed array members

-

-        // TODO(jonskeet): Remove?

-        public void WritePackedArray(FieldType fieldType, int fieldNumber, string fieldName, IEnumerable list)

-        {

-            int calculatedSize = 0;

-            foreach (object element in list)

-            {

-                calculatedSize += ComputeFieldSizeNoTag(fieldType, element);

-            }

-

-            WriteTag(fieldNumber, WireFormat.WireType.LengthDelimited);

-            WriteRawVarint32((uint) calculatedSize);

-

-            foreach (object element in list)

-            {

-                WriteFieldNoTag(fieldType, element);

-            }

-        }

-

         // TODO(jonskeet): A lot of these are really inefficient, due to method group conversions. Fix!

-        public void WritePackedBoolArray(int fieldNumber, string fieldName, RepeatedField<bool> list)

+        public void WritePackedBoolArray(int fieldNumber, RepeatedField<bool> list)

         {

             if (list.Count == 0)

             {

@@ -825,7 +714,7 @@
             }

         }

 

-        public void WritePackedInt32Array(int fieldNumber, string fieldName, RepeatedField<int> list)

+        public void WritePackedInt32Array(int fieldNumber, RepeatedField<int> list)

         {

             if (list.Count == 0)

             {

@@ -840,7 +729,7 @@
             }

         }

 

-        public void WritePackedSInt32Array(int fieldNumber, string fieldName, RepeatedField<int> list)

+        public void WritePackedSInt32Array(int fieldNumber, RepeatedField<int> list)

         {

             if (list.Count == 0)

             {

@@ -855,7 +744,7 @@
             }

         }

 

-        public void WritePackedUInt32Array(int fieldNumber, string fieldName, RepeatedField<uint> list)

+        public void WritePackedUInt32Array(int fieldNumber, RepeatedField<uint> list)

         {

             if (list.Count == 0)

             {

@@ -870,7 +759,7 @@
             }

         }

 

-        public void WritePackedFixed32Array(int fieldNumber, string fieldName, RepeatedField<uint> list)

+        public void WritePackedFixed32Array(int fieldNumber, RepeatedField<uint> list)

         {

             if (list.Count == 0)

             {

@@ -885,7 +774,7 @@
             }

         }

 

-        public void WritePackedSFixed32Array(int fieldNumber, string fieldName, RepeatedField<int> list)

+        public void WritePackedSFixed32Array(int fieldNumber, RepeatedField<int> list)

         {

             if (list.Count == 0)

             {

@@ -900,7 +789,7 @@
             }

         }

 

-        public void WritePackedInt64Array(int fieldNumber, string fieldName, RepeatedField<long> list)

+        public void WritePackedInt64Array(int fieldNumber, RepeatedField<long> list)

         {

             if (list.Count == 0)

             {

@@ -915,7 +804,7 @@
             }

         }

 

-        public void WritePackedSInt64Array(int fieldNumber, string fieldName, RepeatedField<long> list)

+        public void WritePackedSInt64Array(int fieldNumber, RepeatedField<long> list)

         {

             if (list.Count == 0)

             {

@@ -930,7 +819,7 @@
             }

         }

 

-        public void WritePackedUInt64Array(int fieldNumber, string fieldName, RepeatedField<ulong> list)

+        public void WritePackedUInt64Array(int fieldNumber, RepeatedField<ulong> list)

         {

             if (list.Count == 0)

             {

@@ -945,7 +834,7 @@
             }

         }

 

-        public void WritePackedFixed64Array(int fieldNumber, string fieldName, RepeatedField<ulong> list)

+        public void WritePackedFixed64Array(int fieldNumber, RepeatedField<ulong> list)

         {

             if (list.Count == 0)

             {

@@ -960,7 +849,7 @@
             }

         }

 

-        public void WritePackedSFixed64Array(int fieldNumber, string fieldName, RepeatedField<long> list)

+        public void WritePackedSFixed64Array(int fieldNumber, RepeatedField<long> list)

         {

             if (list.Count == 0)

             {

@@ -975,7 +864,7 @@
             }

         }

 

-        public void WritePackedDoubleArray(int fieldNumber, string fieldName, RepeatedField<double> list)

+        public void WritePackedDoubleArray(int fieldNumber, RepeatedField<double> list)

         {

             if (list.Count == 0)

             {

@@ -990,7 +879,7 @@
             }

         }

 

-        public void WritePackedFloatArray(int fieldNumber, string fieldName, RepeatedField<float> list)

+        public void WritePackedFloatArray(int fieldNumber, RepeatedField<float> list)

         {

             if (list.Count == 0)

             {

@@ -1005,7 +894,7 @@
             }

         }

 

-        public void WritePackedEnumArray<T>(int fieldNumber, string fieldName, RepeatedField<T> list)

+        public void WritePackedEnumArray<T>(int fieldNumber, RepeatedField<T> list)

             where T : struct, IComparable, IFormattable

         {

             if (list.Count == 0)

diff --git a/csharp/src/ProtocolBuffers/DescriptorProtos/DescriptorProtoFile.cs b/csharp/src/ProtocolBuffers/DescriptorProtos/DescriptorProtoFile.cs
index eb96dfc..f4af4e2 100644
--- a/csharp/src/ProtocolBuffers/DescriptorProtos/DescriptorProtoFile.cs
+++ b/csharp/src/ProtocolBuffers/DescriptorProtos/DescriptorProtoFile.cs
@@ -323,9 +323,8 @@
       return hash;
     }
 
-    public void WriteTo(pb::ICodedOutputStream output) {
-      string[] fieldNames = _fieldNames;
-      output.WriteMessageArray(1, fieldNames[0], file_);
+    public void WriteTo(pb::CodedOutputStream output) {
+      output.WriteMessageArray(1, file_);
     }
 
     public int CalculateSize() {
@@ -342,16 +341,9 @@
       file_.Add(other.file_);
     }
 
-    public void MergeFrom(pb::ICodedInputStream input) {
+    public void MergeFrom(pb::CodedInputStream input) {
       uint tag;
-      string fieldName;
-      while (input.ReadTag(out tag, out fieldName)) {
-        if (tag == 0 && fieldName != null) {
-          int fieldOrdinal = global::System.Array.BinarySearch(_fieldNames, fieldName, global::System.StringComparer.Ordinal);
-          if (fieldOrdinal >= 0) {
-            tag = _fieldTags[fieldOrdinal];
-          }
-        }
+      while (input.ReadTag(out tag)) {
         switch(tag) {
           case 0:
             throw pb::InvalidProtocolBufferException.InvalidTag();
@@ -361,7 +353,7 @@
             }
             break;
           case 10: {
-            input.ReadMessageArray(tag, fieldName, file_, global::Google.Protobuf.DescriptorProtos.FileDescriptorProto.Parser);
+            input.ReadMessageArray(tag, file_, global::Google.Protobuf.DescriptorProtos.FileDescriptorProto.Parser);
             break;
           }
         }
@@ -510,29 +502,28 @@
       return hash;
     }
 
-    public void WriteTo(pb::ICodedOutputStream output) {
-      string[] fieldNames = _fieldNames;
+    public void WriteTo(pb::CodedOutputStream output) {
       if (Name != "") {
-        output.WriteString(1, fieldNames[4], Name);
+        output.WriteString(1, Name);
       }
       if (Package != "") {
-        output.WriteString(2, fieldNames[6], Package);
+        output.WriteString(2, Package);
       }
-      output.WriteStringArray(3, fieldNames[0], dependency_);
-      output.WriteMessageArray(4, fieldNames[3], messageType_);
-      output.WriteMessageArray(5, fieldNames[1], enumType_);
-      output.WriteMessageArray(6, fieldNames[8], service_);
-      output.WriteMessageArray(7, fieldNames[2], extension_);
+      output.WriteStringArray(3, dependency_);
+      output.WriteMessageArray(4, messageType_);
+      output.WriteMessageArray(5, enumType_);
+      output.WriteMessageArray(6, service_);
+      output.WriteMessageArray(7, extension_);
       if (options_ != null) {
-        output.WriteMessage(8, fieldNames[5], Options);
+        output.WriteMessage(8, Options);
       }
       if (sourceCodeInfo_ != null) {
-        output.WriteMessage(9, fieldNames[9], SourceCodeInfo);
+        output.WriteMessage(9, SourceCodeInfo);
       }
-      output.WriteInt32Array(10, fieldNames[7], publicDependency_);
-      output.WriteInt32Array(11, fieldNames[11], weakDependency_);
+      output.WriteInt32Array(10, publicDependency_);
+      output.WriteInt32Array(11, weakDependency_);
       if (Syntax != "") {
-        output.WriteString(12, fieldNames[10], Syntax);
+        output.WriteString(12, Syntax);
       }
     }
 
@@ -625,16 +616,9 @@
       }
     }
 
-    public void MergeFrom(pb::ICodedInputStream input) {
+    public void MergeFrom(pb::CodedInputStream input) {
       uint tag;
-      string fieldName;
-      while (input.ReadTag(out tag, out fieldName)) {
-        if (tag == 0 && fieldName != null) {
-          int fieldOrdinal = global::System.Array.BinarySearch(_fieldNames, fieldName, global::System.StringComparer.Ordinal);
-          if (fieldOrdinal >= 0) {
-            tag = _fieldTags[fieldOrdinal];
-          }
-        }
+      while (input.ReadTag(out tag)) {
         switch(tag) {
           case 0:
             throw pb::InvalidProtocolBufferException.InvalidTag();
@@ -644,31 +628,31 @@
             }
             break;
           case 10: {
-            input.ReadString(ref name_);
+            name_ = input.ReadString();
             break;
           }
           case 18: {
-            input.ReadString(ref package_);
+            package_ = input.ReadString();
             break;
           }
           case 26: {
-            input.ReadStringArray(tag, fieldName, dependency_);
+            input.ReadStringArray(tag, dependency_);
             break;
           }
           case 34: {
-            input.ReadMessageArray(tag, fieldName, messageType_, global::Google.Protobuf.DescriptorProtos.DescriptorProto.Parser);
+            input.ReadMessageArray(tag, messageType_, global::Google.Protobuf.DescriptorProtos.DescriptorProto.Parser);
             break;
           }
           case 42: {
-            input.ReadMessageArray(tag, fieldName, enumType_, global::Google.Protobuf.DescriptorProtos.EnumDescriptorProto.Parser);
+            input.ReadMessageArray(tag, enumType_, global::Google.Protobuf.DescriptorProtos.EnumDescriptorProto.Parser);
             break;
           }
           case 50: {
-            input.ReadMessageArray(tag, fieldName, service_, global::Google.Protobuf.DescriptorProtos.ServiceDescriptorProto.Parser);
+            input.ReadMessageArray(tag, service_, global::Google.Protobuf.DescriptorProtos.ServiceDescriptorProto.Parser);
             break;
           }
           case 58: {
-            input.ReadMessageArray(tag, fieldName, extension_, global::Google.Protobuf.DescriptorProtos.FieldDescriptorProto.Parser);
+            input.ReadMessageArray(tag, extension_, global::Google.Protobuf.DescriptorProtos.FieldDescriptorProto.Parser);
             break;
           }
           case 66: {
@@ -687,16 +671,16 @@
           }
           case 82:
           case 80: {
-            input.ReadInt32Array(tag, fieldName, publicDependency_);
+            input.ReadInt32Array(tag, publicDependency_);
             break;
           }
           case 90:
           case 88: {
-            input.ReadInt32Array(tag, fieldName, weakDependency_);
+            input.ReadInt32Array(tag, weakDependency_);
             break;
           }
           case 98: {
-            input.ReadString(ref syntax_);
+            syntax_ = input.ReadString();
             break;
           }
         }
@@ -825,22 +809,21 @@
       return hash;
     }
 
-    public void WriteTo(pb::ICodedOutputStream output) {
-      string[] fieldNames = _fieldNames;
+    public void WriteTo(pb::CodedOutputStream output) {
       if (Name != "") {
-        output.WriteString(1, fieldNames[4], Name);
+        output.WriteString(1, Name);
       }
-      output.WriteMessageArray(2, fieldNames[3], field_);
-      output.WriteMessageArray(3, fieldNames[5], nestedType_);
-      output.WriteMessageArray(4, fieldNames[0], enumType_);
-      output.WriteMessageArray(5, fieldNames[2], extensionRange_);
-      output.WriteMessageArray(6, fieldNames[1], extension_);
+      output.WriteMessageArray(2, field_);
+      output.WriteMessageArray(3, nestedType_);
+      output.WriteMessageArray(4, enumType_);
+      output.WriteMessageArray(5, extensionRange_);
+      output.WriteMessageArray(6, extension_);
       if (options_ != null) {
-        output.WriteMessage(7, fieldNames[7], Options);
+        output.WriteMessage(7, Options);
       }
-      output.WriteMessageArray(8, fieldNames[6], oneofDecl_);
-      output.WriteMessageArray(9, fieldNames[9], reservedRange_);
-      output.WriteStringArray(10, fieldNames[8], reservedName_);
+      output.WriteMessageArray(8, oneofDecl_);
+      output.WriteMessageArray(9, reservedRange_);
+      output.WriteStringArray(10, reservedName_);
     }
 
     public int CalculateSize() {
@@ -905,16 +888,9 @@
       reservedName_.Add(other.reservedName_);
     }
 
-    public void MergeFrom(pb::ICodedInputStream input) {
+    public void MergeFrom(pb::CodedInputStream input) {
       uint tag;
-      string fieldName;
-      while (input.ReadTag(out tag, out fieldName)) {
-        if (tag == 0 && fieldName != null) {
-          int fieldOrdinal = global::System.Array.BinarySearch(_fieldNames, fieldName, global::System.StringComparer.Ordinal);
-          if (fieldOrdinal >= 0) {
-            tag = _fieldTags[fieldOrdinal];
-          }
-        }
+      while (input.ReadTag(out tag)) {
         switch(tag) {
           case 0:
             throw pb::InvalidProtocolBufferException.InvalidTag();
@@ -924,27 +900,27 @@
             }
             break;
           case 10: {
-            input.ReadString(ref name_);
+            name_ = input.ReadString();
             break;
           }
           case 18: {
-            input.ReadMessageArray(tag, fieldName, field_, global::Google.Protobuf.DescriptorProtos.FieldDescriptorProto.Parser);
+            input.ReadMessageArray(tag, field_, global::Google.Protobuf.DescriptorProtos.FieldDescriptorProto.Parser);
             break;
           }
           case 26: {
-            input.ReadMessageArray(tag, fieldName, nestedType_, global::Google.Protobuf.DescriptorProtos.DescriptorProto.Parser);
+            input.ReadMessageArray(tag, nestedType_, global::Google.Protobuf.DescriptorProtos.DescriptorProto.Parser);
             break;
           }
           case 34: {
-            input.ReadMessageArray(tag, fieldName, enumType_, global::Google.Protobuf.DescriptorProtos.EnumDescriptorProto.Parser);
+            input.ReadMessageArray(tag, enumType_, global::Google.Protobuf.DescriptorProtos.EnumDescriptorProto.Parser);
             break;
           }
           case 42: {
-            input.ReadMessageArray(tag, fieldName, extensionRange_, global::Google.Protobuf.DescriptorProtos.DescriptorProto.Types.ExtensionRange.Parser);
+            input.ReadMessageArray(tag, extensionRange_, global::Google.Protobuf.DescriptorProtos.DescriptorProto.Types.ExtensionRange.Parser);
             break;
           }
           case 50: {
-            input.ReadMessageArray(tag, fieldName, extension_, global::Google.Protobuf.DescriptorProtos.FieldDescriptorProto.Parser);
+            input.ReadMessageArray(tag, extension_, global::Google.Protobuf.DescriptorProtos.FieldDescriptorProto.Parser);
             break;
           }
           case 58: {
@@ -955,15 +931,15 @@
             break;
           }
           case 66: {
-            input.ReadMessageArray(tag, fieldName, oneofDecl_, global::Google.Protobuf.DescriptorProtos.OneofDescriptorProto.Parser);
+            input.ReadMessageArray(tag, oneofDecl_, global::Google.Protobuf.DescriptorProtos.OneofDescriptorProto.Parser);
             break;
           }
           case 74: {
-            input.ReadMessageArray(tag, fieldName, reservedRange_, global::Google.Protobuf.DescriptorProtos.DescriptorProto.Types.ReservedRange.Parser);
+            input.ReadMessageArray(tag, reservedRange_, global::Google.Protobuf.DescriptorProtos.DescriptorProto.Types.ReservedRange.Parser);
             break;
           }
           case 82: {
-            input.ReadStringArray(tag, fieldName, reservedName_);
+            input.ReadStringArray(tag, reservedName_);
             break;
           }
         }
@@ -1031,13 +1007,12 @@
           return hash;
         }
 
-        public void WriteTo(pb::ICodedOutputStream output) {
-          string[] fieldNames = _fieldNames;
+        public void WriteTo(pb::CodedOutputStream output) {
           if (Start != 0) {
-            output.WriteInt32(1, fieldNames[1], Start);
+            output.WriteInt32(1, Start);
           }
           if (End != 0) {
-            output.WriteInt32(2, fieldNames[0], End);
+            output.WriteInt32(2, End);
           }
         }
 
@@ -1063,16 +1038,9 @@
           }
         }
 
-        public void MergeFrom(pb::ICodedInputStream input) {
+        public void MergeFrom(pb::CodedInputStream input) {
           uint tag;
-          string fieldName;
-          while (input.ReadTag(out tag, out fieldName)) {
-            if (tag == 0 && fieldName != null) {
-              int fieldOrdinal = global::System.Array.BinarySearch(_fieldNames, fieldName, global::System.StringComparer.Ordinal);
-              if (fieldOrdinal >= 0) {
-                tag = _fieldTags[fieldOrdinal];
-              }
-            }
+          while (input.ReadTag(out tag)) {
             switch(tag) {
               case 0:
                 throw pb::InvalidProtocolBufferException.InvalidTag();
@@ -1082,11 +1050,11 @@
                 }
                 break;
               case 8: {
-                input.ReadInt32(ref start_);
+                start_ = input.ReadInt32();
                 break;
               }
               case 16: {
-                input.ReadInt32(ref end_);
+                end_ = input.ReadInt32();
                 break;
               }
             }
@@ -1153,13 +1121,12 @@
           return hash;
         }
 
-        public void WriteTo(pb::ICodedOutputStream output) {
-          string[] fieldNames = _fieldNames;
+        public void WriteTo(pb::CodedOutputStream output) {
           if (Start != 0) {
-            output.WriteInt32(1, fieldNames[1], Start);
+            output.WriteInt32(1, Start);
           }
           if (End != 0) {
-            output.WriteInt32(2, fieldNames[0], End);
+            output.WriteInt32(2, End);
           }
         }
 
@@ -1185,16 +1152,9 @@
           }
         }
 
-        public void MergeFrom(pb::ICodedInputStream input) {
+        public void MergeFrom(pb::CodedInputStream input) {
           uint tag;
-          string fieldName;
-          while (input.ReadTag(out tag, out fieldName)) {
-            if (tag == 0 && fieldName != null) {
-              int fieldOrdinal = global::System.Array.BinarySearch(_fieldNames, fieldName, global::System.StringComparer.Ordinal);
-              if (fieldOrdinal >= 0) {
-                tag = _fieldTags[fieldOrdinal];
-              }
-            }
+          while (input.ReadTag(out tag)) {
             switch(tag) {
               case 0:
                 throw pb::InvalidProtocolBufferException.InvalidTag();
@@ -1204,11 +1164,11 @@
                 }
                 break;
               case 8: {
-                input.ReadInt32(ref start_);
+                start_ = input.ReadInt32();
                 break;
               }
               case 16: {
-                input.ReadInt32(ref end_);
+                end_ = input.ReadInt32();
                 break;
               }
             }
@@ -1348,34 +1308,33 @@
       return hash;
     }
 
-    public void WriteTo(pb::ICodedOutputStream output) {
-      string[] fieldNames = _fieldNames;
+    public void WriteTo(pb::CodedOutputStream output) {
       if (Name != "") {
-        output.WriteString(1, fieldNames[3], Name);
+        output.WriteString(1, Name);
       }
       if (Extendee != "") {
-        output.WriteString(2, fieldNames[1], Extendee);
+        output.WriteString(2, Extendee);
       }
       if (Number != 0) {
-        output.WriteInt32(3, fieldNames[4], Number);
+        output.WriteInt32(3, Number);
       }
       if (Label != global::Google.Protobuf.DescriptorProtos.FieldDescriptorProto.Types.Label.LABEL_OPTIONAL) {
-        output.WriteEnum(4, fieldNames[2], (int) Label);
+        output.WriteEnum(4, (int) Label);
       }
       if (Type != global::Google.Protobuf.DescriptorProtos.FieldDescriptorProto.Types.Type.TYPE_DOUBLE) {
-        output.WriteEnum(5, fieldNames[7], (int) Type);
+        output.WriteEnum(5, (int) Type);
       }
       if (TypeName != "") {
-        output.WriteString(6, fieldNames[8], TypeName);
+        output.WriteString(6, TypeName);
       }
       if (DefaultValue != "") {
-        output.WriteString(7, fieldNames[0], DefaultValue);
+        output.WriteString(7, DefaultValue);
       }
       if (options_ != null) {
-        output.WriteMessage(8, fieldNames[6], Options);
+        output.WriteMessage(8, Options);
       }
       if (OneofIndex != 0) {
-        output.WriteInt32(9, fieldNames[5], OneofIndex);
+        output.WriteInt32(9, OneofIndex);
       }
     }
 
@@ -1446,16 +1405,9 @@
       }
     }
 
-    public void MergeFrom(pb::ICodedInputStream input) {
+    public void MergeFrom(pb::CodedInputStream input) {
       uint tag;
-      string fieldName;
-      while (input.ReadTag(out tag, out fieldName)) {
-        if (tag == 0 && fieldName != null) {
-          int fieldOrdinal = global::System.Array.BinarySearch(_fieldNames, fieldName, global::System.StringComparer.Ordinal);
-          if (fieldOrdinal >= 0) {
-            tag = _fieldTags[fieldOrdinal];
-          }
-        }
+      while (input.ReadTag(out tag)) {
         switch(tag) {
           case 0:
             throw pb::InvalidProtocolBufferException.InvalidTag();
@@ -1465,33 +1417,31 @@
             }
             break;
           case 10: {
-            input.ReadString(ref name_);
+            name_ = input.ReadString();
             break;
           }
           case 18: {
-            input.ReadString(ref extendee_);
+            extendee_ = input.ReadString();
             break;
           }
           case 24: {
-            input.ReadInt32(ref number_);
+            number_ = input.ReadInt32();
             break;
           }
           case 32: {
-            int tmp = 0;
-            input.ReadEnum(ref tmp);
-            label_ = (global::Google.Protobuf.DescriptorProtos.FieldDescriptorProto.Types.Label) tmp;break;
+            label_ = (global::Google.Protobuf.DescriptorProtos.FieldDescriptorProto.Types.Label) input.ReadEnum();
+            break;
           }
           case 40: {
-            int tmp = 0;
-            input.ReadEnum(ref tmp);
-            type_ = (global::Google.Protobuf.DescriptorProtos.FieldDescriptorProto.Types.Type) tmp;break;
+            type_ = (global::Google.Protobuf.DescriptorProtos.FieldDescriptorProto.Types.Type) input.ReadEnum();
+            break;
           }
           case 50: {
-            input.ReadString(ref typeName_);
+            typeName_ = input.ReadString();
             break;
           }
           case 58: {
-            input.ReadString(ref defaultValue_);
+            defaultValue_ = input.ReadString();
             break;
           }
           case 66: {
@@ -1502,7 +1452,7 @@
             break;
           }
           case 72: {
-            input.ReadInt32(ref oneofIndex_);
+            oneofIndex_ = input.ReadInt32();
             break;
           }
         }
@@ -1592,10 +1542,9 @@
       return hash;
     }
 
-    public void WriteTo(pb::ICodedOutputStream output) {
-      string[] fieldNames = _fieldNames;
+    public void WriteTo(pb::CodedOutputStream output) {
       if (Name != "") {
-        output.WriteString(1, fieldNames[0], Name);
+        output.WriteString(1, Name);
       }
     }
 
@@ -1615,16 +1564,9 @@
       }
     }
 
-    public void MergeFrom(pb::ICodedInputStream input) {
+    public void MergeFrom(pb::CodedInputStream input) {
       uint tag;
-      string fieldName;
-      while (input.ReadTag(out tag, out fieldName)) {
-        if (tag == 0 && fieldName != null) {
-          int fieldOrdinal = global::System.Array.BinarySearch(_fieldNames, fieldName, global::System.StringComparer.Ordinal);
-          if (fieldOrdinal >= 0) {
-            tag = _fieldTags[fieldOrdinal];
-          }
-        }
+      while (input.ReadTag(out tag)) {
         switch(tag) {
           case 0:
             throw pb::InvalidProtocolBufferException.InvalidTag();
@@ -1634,7 +1576,7 @@
             }
             break;
           case 10: {
-            input.ReadString(ref name_);
+            name_ = input.ReadString();
             break;
           }
         }
@@ -1707,14 +1649,13 @@
       return hash;
     }
 
-    public void WriteTo(pb::ICodedOutputStream output) {
-      string[] fieldNames = _fieldNames;
+    public void WriteTo(pb::CodedOutputStream output) {
       if (Name != "") {
-        output.WriteString(1, fieldNames[0], Name);
+        output.WriteString(1, Name);
       }
-      output.WriteMessageArray(2, fieldNames[2], value_);
+      output.WriteMessageArray(2, value_);
       if (options_ != null) {
-        output.WriteMessage(3, fieldNames[1], Options);
+        output.WriteMessage(3, Options);
       }
     }
 
@@ -1747,16 +1688,9 @@
       }
     }
 
-    public void MergeFrom(pb::ICodedInputStream input) {
+    public void MergeFrom(pb::CodedInputStream input) {
       uint tag;
-      string fieldName;
-      while (input.ReadTag(out tag, out fieldName)) {
-        if (tag == 0 && fieldName != null) {
-          int fieldOrdinal = global::System.Array.BinarySearch(_fieldNames, fieldName, global::System.StringComparer.Ordinal);
-          if (fieldOrdinal >= 0) {
-            tag = _fieldTags[fieldOrdinal];
-          }
-        }
+      while (input.ReadTag(out tag)) {
         switch(tag) {
           case 0:
             throw pb::InvalidProtocolBufferException.InvalidTag();
@@ -1766,11 +1700,11 @@
             }
             break;
           case 10: {
-            input.ReadString(ref name_);
+            name_ = input.ReadString();
             break;
           }
           case 18: {
-            input.ReadMessageArray(tag, fieldName, value_, global::Google.Protobuf.DescriptorProtos.EnumValueDescriptorProto.Parser);
+            input.ReadMessageArray(tag, value_, global::Google.Protobuf.DescriptorProtos.EnumValueDescriptorProto.Parser);
             break;
           }
           case 26: {
@@ -1852,16 +1786,15 @@
       return hash;
     }
 
-    public void WriteTo(pb::ICodedOutputStream output) {
-      string[] fieldNames = _fieldNames;
+    public void WriteTo(pb::CodedOutputStream output) {
       if (Name != "") {
-        output.WriteString(1, fieldNames[0], Name);
+        output.WriteString(1, Name);
       }
       if (Number != 0) {
-        output.WriteInt32(2, fieldNames[1], Number);
+        output.WriteInt32(2, Number);
       }
       if (options_ != null) {
-        output.WriteMessage(3, fieldNames[2], Options);
+        output.WriteMessage(3, Options);
       }
     }
 
@@ -1896,16 +1829,9 @@
       }
     }
 
-    public void MergeFrom(pb::ICodedInputStream input) {
+    public void MergeFrom(pb::CodedInputStream input) {
       uint tag;
-      string fieldName;
-      while (input.ReadTag(out tag, out fieldName)) {
-        if (tag == 0 && fieldName != null) {
-          int fieldOrdinal = global::System.Array.BinarySearch(_fieldNames, fieldName, global::System.StringComparer.Ordinal);
-          if (fieldOrdinal >= 0) {
-            tag = _fieldTags[fieldOrdinal];
-          }
-        }
+      while (input.ReadTag(out tag)) {
         switch(tag) {
           case 0:
             throw pb::InvalidProtocolBufferException.InvalidTag();
@@ -1915,11 +1841,11 @@
             }
             break;
           case 10: {
-            input.ReadString(ref name_);
+            name_ = input.ReadString();
             break;
           }
           case 16: {
-            input.ReadInt32(ref number_);
+            number_ = input.ReadInt32();
             break;
           }
           case 26: {
@@ -1999,14 +1925,13 @@
       return hash;
     }
 
-    public void WriteTo(pb::ICodedOutputStream output) {
-      string[] fieldNames = _fieldNames;
+    public void WriteTo(pb::CodedOutputStream output) {
       if (Name != "") {
-        output.WriteString(1, fieldNames[1], Name);
+        output.WriteString(1, Name);
       }
-      output.WriteMessageArray(2, fieldNames[0], method_);
+      output.WriteMessageArray(2, method_);
       if (options_ != null) {
-        output.WriteMessage(3, fieldNames[2], Options);
+        output.WriteMessage(3, Options);
       }
     }
 
@@ -2039,16 +1964,9 @@
       }
     }
 
-    public void MergeFrom(pb::ICodedInputStream input) {
+    public void MergeFrom(pb::CodedInputStream input) {
       uint tag;
-      string fieldName;
-      while (input.ReadTag(out tag, out fieldName)) {
-        if (tag == 0 && fieldName != null) {
-          int fieldOrdinal = global::System.Array.BinarySearch(_fieldNames, fieldName, global::System.StringComparer.Ordinal);
-          if (fieldOrdinal >= 0) {
-            tag = _fieldTags[fieldOrdinal];
-          }
-        }
+      while (input.ReadTag(out tag)) {
         switch(tag) {
           case 0:
             throw pb::InvalidProtocolBufferException.InvalidTag();
@@ -2058,11 +1976,11 @@
             }
             break;
           case 10: {
-            input.ReadString(ref name_);
+            name_ = input.ReadString();
             break;
           }
           case 18: {
-            input.ReadMessageArray(tag, fieldName, method_, global::Google.Protobuf.DescriptorProtos.MethodDescriptorProto.Parser);
+            input.ReadMessageArray(tag, method_, global::Google.Protobuf.DescriptorProtos.MethodDescriptorProto.Parser);
             break;
           }
           case 26: {
@@ -2174,25 +2092,24 @@
       return hash;
     }
 
-    public void WriteTo(pb::ICodedOutputStream output) {
-      string[] fieldNames = _fieldNames;
+    public void WriteTo(pb::CodedOutputStream output) {
       if (Name != "") {
-        output.WriteString(1, fieldNames[2], Name);
+        output.WriteString(1, Name);
       }
       if (InputType != "") {
-        output.WriteString(2, fieldNames[1], InputType);
+        output.WriteString(2, InputType);
       }
       if (OutputType != "") {
-        output.WriteString(3, fieldNames[4], OutputType);
+        output.WriteString(3, OutputType);
       }
       if (options_ != null) {
-        output.WriteMessage(4, fieldNames[3], Options);
+        output.WriteMessage(4, Options);
       }
       if (ClientStreaming != false) {
-        output.WriteBool(5, fieldNames[0], ClientStreaming);
+        output.WriteBool(5, ClientStreaming);
       }
       if (ServerStreaming != false) {
-        output.WriteBool(6, fieldNames[5], ServerStreaming);
+        output.WriteBool(6, ServerStreaming);
       }
     }
 
@@ -2245,16 +2162,9 @@
       }
     }
 
-    public void MergeFrom(pb::ICodedInputStream input) {
+    public void MergeFrom(pb::CodedInputStream input) {
       uint tag;
-      string fieldName;
-      while (input.ReadTag(out tag, out fieldName)) {
-        if (tag == 0 && fieldName != null) {
-          int fieldOrdinal = global::System.Array.BinarySearch(_fieldNames, fieldName, global::System.StringComparer.Ordinal);
-          if (fieldOrdinal >= 0) {
-            tag = _fieldTags[fieldOrdinal];
-          }
-        }
+      while (input.ReadTag(out tag)) {
         switch(tag) {
           case 0:
             throw pb::InvalidProtocolBufferException.InvalidTag();
@@ -2264,15 +2174,15 @@
             }
             break;
           case 10: {
-            input.ReadString(ref name_);
+            name_ = input.ReadString();
             break;
           }
           case 18: {
-            input.ReadString(ref inputType_);
+            inputType_ = input.ReadString();
             break;
           }
           case 26: {
-            input.ReadString(ref outputType_);
+            outputType_ = input.ReadString();
             break;
           }
           case 34: {
@@ -2283,11 +2193,11 @@
             break;
           }
           case 40: {
-            input.ReadBool(ref clientStreaming_);
+            clientStreaming_ = input.ReadBool();
             break;
           }
           case 48: {
-            input.ReadBool(ref serverStreaming_);
+            serverStreaming_ = input.ReadBool();
             break;
           }
         }
@@ -2482,51 +2392,50 @@
       return hash;
     }
 
-    public void WriteTo(pb::ICodedOutputStream output) {
-      string[] fieldNames = _fieldNames;
+    public void WriteTo(pb::CodedOutputStream output) {
       if (JavaPackage != "") {
-        output.WriteString(1, fieldNames[9], JavaPackage);
+        output.WriteString(1, JavaPackage);
       }
       if (JavaOuterClassname != "") {
-        output.WriteString(8, fieldNames[8], JavaOuterClassname);
+        output.WriteString(8, JavaOuterClassname);
       }
       if (OptimizeFor != global::Google.Protobuf.DescriptorProtos.FileOptions.Types.OptimizeMode.SPEED) {
-        output.WriteEnum(9, fieldNames[12], (int) OptimizeFor);
+        output.WriteEnum(9, (int) OptimizeFor);
       }
       if (JavaMultipleFiles != false) {
-        output.WriteBool(10, fieldNames[7], JavaMultipleFiles);
+        output.WriteBool(10, JavaMultipleFiles);
       }
       if (GoPackage != "") {
-        output.WriteString(11, fieldNames[4], GoPackage);
+        output.WriteString(11, GoPackage);
       }
       if (CcGenericServices != false) {
-        output.WriteBool(16, fieldNames[1], CcGenericServices);
+        output.WriteBool(16, CcGenericServices);
       }
       if (JavaGenericServices != false) {
-        output.WriteBool(17, fieldNames[6], JavaGenericServices);
+        output.WriteBool(17, JavaGenericServices);
       }
       if (PyGenericServices != false) {
-        output.WriteBool(18, fieldNames[13], PyGenericServices);
+        output.WriteBool(18, PyGenericServices);
       }
       if (JavaGenerateEqualsAndHash != false) {
-        output.WriteBool(20, fieldNames[5], JavaGenerateEqualsAndHash);
+        output.WriteBool(20, JavaGenerateEqualsAndHash);
       }
       if (Deprecated != false) {
-        output.WriteBool(23, fieldNames[3], Deprecated);
+        output.WriteBool(23, Deprecated);
       }
       if (JavaStringCheckUtf8 != false) {
-        output.WriteBool(27, fieldNames[10], JavaStringCheckUtf8);
+        output.WriteBool(27, JavaStringCheckUtf8);
       }
       if (CcEnableArenas != false) {
-        output.WriteBool(31, fieldNames[0], CcEnableArenas);
+        output.WriteBool(31, CcEnableArenas);
       }
       if (ObjcClassPrefix != "") {
-        output.WriteString(36, fieldNames[11], ObjcClassPrefix);
+        output.WriteString(36, ObjcClassPrefix);
       }
       if (CsharpNamespace != "") {
-        output.WriteString(37, fieldNames[2], CsharpNamespace);
+        output.WriteString(37, CsharpNamespace);
       }
-      output.WriteMessageArray(999, fieldNames[14], uninterpretedOption_);
+      output.WriteMessageArray(999, uninterpretedOption_);
     }
 
     public int CalculateSize() {
@@ -2627,16 +2536,9 @@
       uninterpretedOption_.Add(other.uninterpretedOption_);
     }
 
-    public void MergeFrom(pb::ICodedInputStream input) {
+    public void MergeFrom(pb::CodedInputStream input) {
       uint tag;
-      string fieldName;
-      while (input.ReadTag(out tag, out fieldName)) {
-        if (tag == 0 && fieldName != null) {
-          int fieldOrdinal = global::System.Array.BinarySearch(_fieldNames, fieldName, global::System.StringComparer.Ordinal);
-          if (fieldOrdinal >= 0) {
-            tag = _fieldTags[fieldOrdinal];
-          }
-        }
+      while (input.ReadTag(out tag)) {
         switch(tag) {
           case 0:
             throw pb::InvalidProtocolBufferException.InvalidTag();
@@ -2646,64 +2548,63 @@
             }
             break;
           case 10: {
-            input.ReadString(ref javaPackage_);
+            javaPackage_ = input.ReadString();
             break;
           }
           case 66: {
-            input.ReadString(ref javaOuterClassname_);
+            javaOuterClassname_ = input.ReadString();
             break;
           }
           case 72: {
-            int tmp = 0;
-            input.ReadEnum(ref tmp);
-            optimizeFor_ = (global::Google.Protobuf.DescriptorProtos.FileOptions.Types.OptimizeMode) tmp;break;
+            optimizeFor_ = (global::Google.Protobuf.DescriptorProtos.FileOptions.Types.OptimizeMode) input.ReadEnum();
+            break;
           }
           case 80: {
-            input.ReadBool(ref javaMultipleFiles_);
+            javaMultipleFiles_ = input.ReadBool();
             break;
           }
           case 90: {
-            input.ReadString(ref goPackage_);
+            goPackage_ = input.ReadString();
             break;
           }
           case 128: {
-            input.ReadBool(ref ccGenericServices_);
+            ccGenericServices_ = input.ReadBool();
             break;
           }
           case 136: {
-            input.ReadBool(ref javaGenericServices_);
+            javaGenericServices_ = input.ReadBool();
             break;
           }
           case 144: {
-            input.ReadBool(ref pyGenericServices_);
+            pyGenericServices_ = input.ReadBool();
             break;
           }
           case 160: {
-            input.ReadBool(ref javaGenerateEqualsAndHash_);
+            javaGenerateEqualsAndHash_ = input.ReadBool();
             break;
           }
           case 184: {
-            input.ReadBool(ref deprecated_);
+            deprecated_ = input.ReadBool();
             break;
           }
           case 216: {
-            input.ReadBool(ref javaStringCheckUtf8_);
+            javaStringCheckUtf8_ = input.ReadBool();
             break;
           }
           case 248: {
-            input.ReadBool(ref ccEnableArenas_);
+            ccEnableArenas_ = input.ReadBool();
             break;
           }
           case 290: {
-            input.ReadString(ref objcClassPrefix_);
+            objcClassPrefix_ = input.ReadString();
             break;
           }
           case 298: {
-            input.ReadString(ref csharpNamespace_);
+            csharpNamespace_ = input.ReadString();
             break;
           }
           case 7994: {
-            input.ReadMessageArray(tag, fieldName, uninterpretedOption_, global::Google.Protobuf.DescriptorProtos.UninterpretedOption.Parser);
+            input.ReadMessageArray(tag, uninterpretedOption_, global::Google.Protobuf.DescriptorProtos.UninterpretedOption.Parser);
             break;
           }
         }
@@ -2810,21 +2711,20 @@
       return hash;
     }
 
-    public void WriteTo(pb::ICodedOutputStream output) {
-      string[] fieldNames = _fieldNames;
+    public void WriteTo(pb::CodedOutputStream output) {
       if (MessageSetWireFormat != false) {
-        output.WriteBool(1, fieldNames[2], MessageSetWireFormat);
+        output.WriteBool(1, MessageSetWireFormat);
       }
       if (NoStandardDescriptorAccessor != false) {
-        output.WriteBool(2, fieldNames[3], NoStandardDescriptorAccessor);
+        output.WriteBool(2, NoStandardDescriptorAccessor);
       }
       if (Deprecated != false) {
-        output.WriteBool(3, fieldNames[0], Deprecated);
+        output.WriteBool(3, Deprecated);
       }
       if (MapEntry != false) {
-        output.WriteBool(7, fieldNames[1], MapEntry);
+        output.WriteBool(7, MapEntry);
       }
-      output.WriteMessageArray(999, fieldNames[4], uninterpretedOption_);
+      output.WriteMessageArray(999, uninterpretedOption_);
     }
 
     public int CalculateSize() {
@@ -2865,16 +2765,9 @@
       uninterpretedOption_.Add(other.uninterpretedOption_);
     }
 
-    public void MergeFrom(pb::ICodedInputStream input) {
+    public void MergeFrom(pb::CodedInputStream input) {
       uint tag;
-      string fieldName;
-      while (input.ReadTag(out tag, out fieldName)) {
-        if (tag == 0 && fieldName != null) {
-          int fieldOrdinal = global::System.Array.BinarySearch(_fieldNames, fieldName, global::System.StringComparer.Ordinal);
-          if (fieldOrdinal >= 0) {
-            tag = _fieldTags[fieldOrdinal];
-          }
-        }
+      while (input.ReadTag(out tag)) {
         switch(tag) {
           case 0:
             throw pb::InvalidProtocolBufferException.InvalidTag();
@@ -2884,23 +2777,23 @@
             }
             break;
           case 8: {
-            input.ReadBool(ref messageSetWireFormat_);
+            messageSetWireFormat_ = input.ReadBool();
             break;
           }
           case 16: {
-            input.ReadBool(ref noStandardDescriptorAccessor_);
+            noStandardDescriptorAccessor_ = input.ReadBool();
             break;
           }
           case 24: {
-            input.ReadBool(ref deprecated_);
+            deprecated_ = input.ReadBool();
             break;
           }
           case 56: {
-            input.ReadBool(ref mapEntry_);
+            mapEntry_ = input.ReadBool();
             break;
           }
           case 7994: {
-            input.ReadMessageArray(tag, fieldName, uninterpretedOption_, global::Google.Protobuf.DescriptorProtos.UninterpretedOption.Parser);
+            input.ReadMessageArray(tag, uninterpretedOption_, global::Google.Protobuf.DescriptorProtos.UninterpretedOption.Parser);
             break;
           }
         }
@@ -3015,27 +2908,26 @@
       return hash;
     }
 
-    public void WriteTo(pb::ICodedOutputStream output) {
-      string[] fieldNames = _fieldNames;
+    public void WriteTo(pb::CodedOutputStream output) {
       if (Ctype != global::Google.Protobuf.DescriptorProtos.FieldOptions.Types.CType.STRING) {
-        output.WriteEnum(1, fieldNames[0], (int) Ctype);
+        output.WriteEnum(1, (int) Ctype);
       }
       if (Packed != false) {
-        output.WriteBool(2, fieldNames[4], Packed);
+        output.WriteBool(2, Packed);
       }
       if (Deprecated != false) {
-        output.WriteBool(3, fieldNames[1], Deprecated);
+        output.WriteBool(3, Deprecated);
       }
       if (Lazy != false) {
-        output.WriteBool(5, fieldNames[3], Lazy);
+        output.WriteBool(5, Lazy);
       }
       if (Jstype != global::Google.Protobuf.DescriptorProtos.FieldOptions.Types.JSType.JS_NORMAL) {
-        output.WriteEnum(6, fieldNames[2], (int) Jstype);
+        output.WriteEnum(6, (int) Jstype);
       }
       if (Weak != false) {
-        output.WriteBool(10, fieldNames[6], Weak);
+        output.WriteBool(10, Weak);
       }
-      output.WriteMessageArray(999, fieldNames[5], uninterpretedOption_);
+      output.WriteMessageArray(999, uninterpretedOption_);
     }
 
     public int CalculateSize() {
@@ -3088,16 +2980,9 @@
       uninterpretedOption_.Add(other.uninterpretedOption_);
     }
 
-    public void MergeFrom(pb::ICodedInputStream input) {
+    public void MergeFrom(pb::CodedInputStream input) {
       uint tag;
-      string fieldName;
-      while (input.ReadTag(out tag, out fieldName)) {
-        if (tag == 0 && fieldName != null) {
-          int fieldOrdinal = global::System.Array.BinarySearch(_fieldNames, fieldName, global::System.StringComparer.Ordinal);
-          if (fieldOrdinal >= 0) {
-            tag = _fieldTags[fieldOrdinal];
-          }
-        }
+      while (input.ReadTag(out tag)) {
         switch(tag) {
           case 0:
             throw pb::InvalidProtocolBufferException.InvalidTag();
@@ -3107,33 +2992,31 @@
             }
             break;
           case 8: {
-            int tmp = 0;
-            input.ReadEnum(ref tmp);
-            ctype_ = (global::Google.Protobuf.DescriptorProtos.FieldOptions.Types.CType) tmp;break;
+            ctype_ = (global::Google.Protobuf.DescriptorProtos.FieldOptions.Types.CType) input.ReadEnum();
+            break;
           }
           case 16: {
-            input.ReadBool(ref packed_);
+            packed_ = input.ReadBool();
             break;
           }
           case 24: {
-            input.ReadBool(ref deprecated_);
+            deprecated_ = input.ReadBool();
             break;
           }
           case 40: {
-            input.ReadBool(ref lazy_);
+            lazy_ = input.ReadBool();
             break;
           }
           case 48: {
-            int tmp = 0;
-            input.ReadEnum(ref tmp);
-            jstype_ = (global::Google.Protobuf.DescriptorProtos.FieldOptions.Types.JSType) tmp;break;
+            jstype_ = (global::Google.Protobuf.DescriptorProtos.FieldOptions.Types.JSType) input.ReadEnum();
+            break;
           }
           case 80: {
-            input.ReadBool(ref weak_);
+            weak_ = input.ReadBool();
             break;
           }
           case 7994: {
-            input.ReadMessageArray(tag, fieldName, uninterpretedOption_, global::Google.Protobuf.DescriptorProtos.UninterpretedOption.Parser);
+            input.ReadMessageArray(tag, uninterpretedOption_, global::Google.Protobuf.DescriptorProtos.UninterpretedOption.Parser);
             break;
           }
         }
@@ -3226,15 +3109,14 @@
       return hash;
     }
 
-    public void WriteTo(pb::ICodedOutputStream output) {
-      string[] fieldNames = _fieldNames;
+    public void WriteTo(pb::CodedOutputStream output) {
       if (AllowAlias != false) {
-        output.WriteBool(2, fieldNames[0], AllowAlias);
+        output.WriteBool(2, AllowAlias);
       }
       if (Deprecated != false) {
-        output.WriteBool(3, fieldNames[1], Deprecated);
+        output.WriteBool(3, Deprecated);
       }
-      output.WriteMessageArray(999, fieldNames[2], uninterpretedOption_);
+      output.WriteMessageArray(999, uninterpretedOption_);
     }
 
     public int CalculateSize() {
@@ -3263,16 +3145,9 @@
       uninterpretedOption_.Add(other.uninterpretedOption_);
     }
 
-    public void MergeFrom(pb::ICodedInputStream input) {
+    public void MergeFrom(pb::CodedInputStream input) {
       uint tag;
-      string fieldName;
-      while (input.ReadTag(out tag, out fieldName)) {
-        if (tag == 0 && fieldName != null) {
-          int fieldOrdinal = global::System.Array.BinarySearch(_fieldNames, fieldName, global::System.StringComparer.Ordinal);
-          if (fieldOrdinal >= 0) {
-            tag = _fieldTags[fieldOrdinal];
-          }
-        }
+      while (input.ReadTag(out tag)) {
         switch(tag) {
           case 0:
             throw pb::InvalidProtocolBufferException.InvalidTag();
@@ -3282,15 +3157,15 @@
             }
             break;
           case 16: {
-            input.ReadBool(ref allowAlias_);
+            allowAlias_ = input.ReadBool();
             break;
           }
           case 24: {
-            input.ReadBool(ref deprecated_);
+            deprecated_ = input.ReadBool();
             break;
           }
           case 7994: {
-            input.ReadMessageArray(tag, fieldName, uninterpretedOption_, global::Google.Protobuf.DescriptorProtos.UninterpretedOption.Parser);
+            input.ReadMessageArray(tag, uninterpretedOption_, global::Google.Protobuf.DescriptorProtos.UninterpretedOption.Parser);
             break;
           }
         }
@@ -3355,12 +3230,11 @@
       return hash;
     }
 
-    public void WriteTo(pb::ICodedOutputStream output) {
-      string[] fieldNames = _fieldNames;
+    public void WriteTo(pb::CodedOutputStream output) {
       if (Deprecated != false) {
-        output.WriteBool(1, fieldNames[0], Deprecated);
+        output.WriteBool(1, Deprecated);
       }
-      output.WriteMessageArray(999, fieldNames[1], uninterpretedOption_);
+      output.WriteMessageArray(999, uninterpretedOption_);
     }
 
     public int CalculateSize() {
@@ -3383,16 +3257,9 @@
       uninterpretedOption_.Add(other.uninterpretedOption_);
     }
 
-    public void MergeFrom(pb::ICodedInputStream input) {
+    public void MergeFrom(pb::CodedInputStream input) {
       uint tag;
-      string fieldName;
-      while (input.ReadTag(out tag, out fieldName)) {
-        if (tag == 0 && fieldName != null) {
-          int fieldOrdinal = global::System.Array.BinarySearch(_fieldNames, fieldName, global::System.StringComparer.Ordinal);
-          if (fieldOrdinal >= 0) {
-            tag = _fieldTags[fieldOrdinal];
-          }
-        }
+      while (input.ReadTag(out tag)) {
         switch(tag) {
           case 0:
             throw pb::InvalidProtocolBufferException.InvalidTag();
@@ -3402,11 +3269,11 @@
             }
             break;
           case 8: {
-            input.ReadBool(ref deprecated_);
+            deprecated_ = input.ReadBool();
             break;
           }
           case 7994: {
-            input.ReadMessageArray(tag, fieldName, uninterpretedOption_, global::Google.Protobuf.DescriptorProtos.UninterpretedOption.Parser);
+            input.ReadMessageArray(tag, uninterpretedOption_, global::Google.Protobuf.DescriptorProtos.UninterpretedOption.Parser);
             break;
           }
         }
@@ -3471,12 +3338,11 @@
       return hash;
     }
 
-    public void WriteTo(pb::ICodedOutputStream output) {
-      string[] fieldNames = _fieldNames;
+    public void WriteTo(pb::CodedOutputStream output) {
       if (Deprecated != false) {
-        output.WriteBool(33, fieldNames[0], Deprecated);
+        output.WriteBool(33, Deprecated);
       }
-      output.WriteMessageArray(999, fieldNames[1], uninterpretedOption_);
+      output.WriteMessageArray(999, uninterpretedOption_);
     }
 
     public int CalculateSize() {
@@ -3499,16 +3365,9 @@
       uninterpretedOption_.Add(other.uninterpretedOption_);
     }
 
-    public void MergeFrom(pb::ICodedInputStream input) {
+    public void MergeFrom(pb::CodedInputStream input) {
       uint tag;
-      string fieldName;
-      while (input.ReadTag(out tag, out fieldName)) {
-        if (tag == 0 && fieldName != null) {
-          int fieldOrdinal = global::System.Array.BinarySearch(_fieldNames, fieldName, global::System.StringComparer.Ordinal);
-          if (fieldOrdinal >= 0) {
-            tag = _fieldTags[fieldOrdinal];
-          }
-        }
+      while (input.ReadTag(out tag)) {
         switch(tag) {
           case 0:
             throw pb::InvalidProtocolBufferException.InvalidTag();
@@ -3518,11 +3377,11 @@
             }
             break;
           case 264: {
-            input.ReadBool(ref deprecated_);
+            deprecated_ = input.ReadBool();
             break;
           }
           case 7994: {
-            input.ReadMessageArray(tag, fieldName, uninterpretedOption_, global::Google.Protobuf.DescriptorProtos.UninterpretedOption.Parser);
+            input.ReadMessageArray(tag, uninterpretedOption_, global::Google.Protobuf.DescriptorProtos.UninterpretedOption.Parser);
             break;
           }
         }
@@ -3587,12 +3446,11 @@
       return hash;
     }
 
-    public void WriteTo(pb::ICodedOutputStream output) {
-      string[] fieldNames = _fieldNames;
+    public void WriteTo(pb::CodedOutputStream output) {
       if (Deprecated != false) {
-        output.WriteBool(33, fieldNames[0], Deprecated);
+        output.WriteBool(33, Deprecated);
       }
-      output.WriteMessageArray(999, fieldNames[1], uninterpretedOption_);
+      output.WriteMessageArray(999, uninterpretedOption_);
     }
 
     public int CalculateSize() {
@@ -3615,16 +3473,9 @@
       uninterpretedOption_.Add(other.uninterpretedOption_);
     }
 
-    public void MergeFrom(pb::ICodedInputStream input) {
+    public void MergeFrom(pb::CodedInputStream input) {
       uint tag;
-      string fieldName;
-      while (input.ReadTag(out tag, out fieldName)) {
-        if (tag == 0 && fieldName != null) {
-          int fieldOrdinal = global::System.Array.BinarySearch(_fieldNames, fieldName, global::System.StringComparer.Ordinal);
-          if (fieldOrdinal >= 0) {
-            tag = _fieldTags[fieldOrdinal];
-          }
-        }
+      while (input.ReadTag(out tag)) {
         switch(tag) {
           case 0:
             throw pb::InvalidProtocolBufferException.InvalidTag();
@@ -3634,11 +3485,11 @@
             }
             break;
           case 264: {
-            input.ReadBool(ref deprecated_);
+            deprecated_ = input.ReadBool();
             break;
           }
           case 7994: {
-            input.ReadMessageArray(tag, fieldName, uninterpretedOption_, global::Google.Protobuf.DescriptorProtos.UninterpretedOption.Parser);
+            input.ReadMessageArray(tag, uninterpretedOption_, global::Google.Protobuf.DescriptorProtos.UninterpretedOption.Parser);
             break;
           }
         }
@@ -3753,26 +3604,25 @@
       return hash;
     }
 
-    public void WriteTo(pb::ICodedOutputStream output) {
-      string[] fieldNames = _fieldNames;
-      output.WriteMessageArray(2, fieldNames[3], name_);
+    public void WriteTo(pb::CodedOutputStream output) {
+      output.WriteMessageArray(2, name_);
       if (IdentifierValue != "") {
-        output.WriteString(3, fieldNames[2], IdentifierValue);
+        output.WriteString(3, IdentifierValue);
       }
       if (PositiveIntValue != 0UL) {
-        output.WriteUInt64(4, fieldNames[5], PositiveIntValue);
+        output.WriteUInt64(4, PositiveIntValue);
       }
       if (NegativeIntValue != 0L) {
-        output.WriteInt64(5, fieldNames[4], NegativeIntValue);
+        output.WriteInt64(5, NegativeIntValue);
       }
       if (DoubleValue != 0D) {
-        output.WriteDouble(6, fieldNames[1], DoubleValue);
+        output.WriteDouble(6, DoubleValue);
       }
       if (StringValue != pb::ByteString.Empty) {
-        output.WriteBytes(7, fieldNames[6], StringValue);
+        output.WriteBytes(7, StringValue);
       }
       if (AggregateValue != "") {
-        output.WriteString(8, fieldNames[0], AggregateValue);
+        output.WriteString(8, AggregateValue);
       }
     }
 
@@ -3826,16 +3676,9 @@
       }
     }
 
-    public void MergeFrom(pb::ICodedInputStream input) {
+    public void MergeFrom(pb::CodedInputStream input) {
       uint tag;
-      string fieldName;
-      while (input.ReadTag(out tag, out fieldName)) {
-        if (tag == 0 && fieldName != null) {
-          int fieldOrdinal = global::System.Array.BinarySearch(_fieldNames, fieldName, global::System.StringComparer.Ordinal);
-          if (fieldOrdinal >= 0) {
-            tag = _fieldTags[fieldOrdinal];
-          }
-        }
+      while (input.ReadTag(out tag)) {
         switch(tag) {
           case 0:
             throw pb::InvalidProtocolBufferException.InvalidTag();
@@ -3845,31 +3688,31 @@
             }
             break;
           case 18: {
-            input.ReadMessageArray(tag, fieldName, name_, global::Google.Protobuf.DescriptorProtos.UninterpretedOption.Types.NamePart.Parser);
+            input.ReadMessageArray(tag, name_, global::Google.Protobuf.DescriptorProtos.UninterpretedOption.Types.NamePart.Parser);
             break;
           }
           case 26: {
-            input.ReadString(ref identifierValue_);
+            identifierValue_ = input.ReadString();
             break;
           }
           case 32: {
-            input.ReadUInt64(ref positiveIntValue_);
+            positiveIntValue_ = input.ReadUInt64();
             break;
           }
           case 40: {
-            input.ReadInt64(ref negativeIntValue_);
+            negativeIntValue_ = input.ReadInt64();
             break;
           }
           case 49: {
-            input.ReadDouble(ref doubleValue_);
+            doubleValue_ = input.ReadDouble();
             break;
           }
           case 58: {
-            input.ReadBytes(ref stringValue_);
+            stringValue_ = input.ReadBytes();
             break;
           }
           case 66: {
-            input.ReadString(ref aggregateValue_);
+            aggregateValue_ = input.ReadString();
             break;
           }
         }
@@ -3937,13 +3780,12 @@
           return hash;
         }
 
-        public void WriteTo(pb::ICodedOutputStream output) {
-          string[] fieldNames = _fieldNames;
+        public void WriteTo(pb::CodedOutputStream output) {
           if (NamePart_ != "") {
-            output.WriteString(1, fieldNames[1], NamePart_);
+            output.WriteString(1, NamePart_);
           }
           if (IsExtension != false) {
-            output.WriteBool(2, fieldNames[0], IsExtension);
+            output.WriteBool(2, IsExtension);
           }
         }
 
@@ -3969,16 +3811,9 @@
           }
         }
 
-        public void MergeFrom(pb::ICodedInputStream input) {
+        public void MergeFrom(pb::CodedInputStream input) {
           uint tag;
-          string fieldName;
-          while (input.ReadTag(out tag, out fieldName)) {
-            if (tag == 0 && fieldName != null) {
-              int fieldOrdinal = global::System.Array.BinarySearch(_fieldNames, fieldName, global::System.StringComparer.Ordinal);
-              if (fieldOrdinal >= 0) {
-                tag = _fieldTags[fieldOrdinal];
-              }
-            }
+          while (input.ReadTag(out tag)) {
             switch(tag) {
               case 0:
                 throw pb::InvalidProtocolBufferException.InvalidTag();
@@ -3988,11 +3823,11 @@
                 }
                 break;
               case 10: {
-                input.ReadString(ref namePart_);
+                namePart_ = input.ReadString();
                 break;
               }
               case 16: {
-                input.ReadBool(ref isExtension_);
+                isExtension_ = input.ReadBool();
                 break;
               }
             }
@@ -4052,9 +3887,8 @@
       return hash;
     }
 
-    public void WriteTo(pb::ICodedOutputStream output) {
-      string[] fieldNames = _fieldNames;
-      output.WriteMessageArray(1, fieldNames[0], location_);
+    public void WriteTo(pb::CodedOutputStream output) {
+      output.WriteMessageArray(1, location_);
     }
 
     public int CalculateSize() {
@@ -4071,16 +3905,9 @@
       location_.Add(other.location_);
     }
 
-    public void MergeFrom(pb::ICodedInputStream input) {
+    public void MergeFrom(pb::CodedInputStream input) {
       uint tag;
-      string fieldName;
-      while (input.ReadTag(out tag, out fieldName)) {
-        if (tag == 0 && fieldName != null) {
-          int fieldOrdinal = global::System.Array.BinarySearch(_fieldNames, fieldName, global::System.StringComparer.Ordinal);
-          if (fieldOrdinal >= 0) {
-            tag = _fieldTags[fieldOrdinal];
-          }
-        }
+      while (input.ReadTag(out tag)) {
         switch(tag) {
           case 0:
             throw pb::InvalidProtocolBufferException.InvalidTag();
@@ -4090,7 +3917,7 @@
             }
             break;
           case 10: {
-            input.ReadMessageArray(tag, fieldName, location_, global::Google.Protobuf.DescriptorProtos.SourceCodeInfo.Types.Location.Parser);
+            input.ReadMessageArray(tag, location_, global::Google.Protobuf.DescriptorProtos.SourceCodeInfo.Types.Location.Parser);
             break;
           }
         }
@@ -4182,17 +4009,16 @@
           return hash;
         }
 
-        public void WriteTo(pb::ICodedOutputStream output) {
-          string[] fieldNames = _fieldNames;
-          output.WritePackedInt32Array(1, fieldNames[2], path_);
-          output.WritePackedInt32Array(2, fieldNames[3], span_);
+        public void WriteTo(pb::CodedOutputStream output) {
+          output.WritePackedInt32Array(1, path_);
+          output.WritePackedInt32Array(2, span_);
           if (LeadingComments != "") {
-            output.WriteString(3, fieldNames[0], LeadingComments);
+            output.WriteString(3, LeadingComments);
           }
           if (TrailingComments != "") {
-            output.WriteString(4, fieldNames[4], TrailingComments);
+            output.WriteString(4, TrailingComments);
           }
-          output.WriteStringArray(6, fieldNames[1], leadingDetachedComments_);
+          output.WriteStringArray(6, leadingDetachedComments_);
         }
 
         public int CalculateSize() {
@@ -4248,16 +4074,9 @@
           leadingDetachedComments_.Add(other.leadingDetachedComments_);
         }
 
-        public void MergeFrom(pb::ICodedInputStream input) {
+        public void MergeFrom(pb::CodedInputStream input) {
           uint tag;
-          string fieldName;
-          while (input.ReadTag(out tag, out fieldName)) {
-            if (tag == 0 && fieldName != null) {
-              int fieldOrdinal = global::System.Array.BinarySearch(_fieldNames, fieldName, global::System.StringComparer.Ordinal);
-              if (fieldOrdinal >= 0) {
-                tag = _fieldTags[fieldOrdinal];
-              }
-            }
+          while (input.ReadTag(out tag)) {
             switch(tag) {
               case 0:
                 throw pb::InvalidProtocolBufferException.InvalidTag();
@@ -4268,24 +4087,24 @@
                 break;
               case 10:
               case 8: {
-                input.ReadInt32Array(tag, fieldName, path_);
+                input.ReadInt32Array(tag, path_);
                 break;
               }
               case 18:
               case 16: {
-                input.ReadInt32Array(tag, fieldName, span_);
+                input.ReadInt32Array(tag, span_);
                 break;
               }
               case 26: {
-                input.ReadString(ref leadingComments_);
+                leadingComments_ = input.ReadString();
                 break;
               }
               case 34: {
-                input.ReadString(ref trailingComments_);
+                trailingComments_ = input.ReadString();
                 break;
               }
               case 50: {
-                input.ReadStringArray(tag, fieldName, leadingDetachedComments_);
+                input.ReadStringArray(tag, leadingDetachedComments_);
                 break;
               }
             }
diff --git a/csharp/src/ProtocolBuffers/Extensions.cs b/csharp/src/ProtocolBuffers/Extensions.cs
index 29288f5..7f23057 100644
--- a/csharp/src/ProtocolBuffers/Extensions.cs
+++ b/csharp/src/ProtocolBuffers/Extensions.cs
@@ -49,7 +49,7 @@
             codedOutput.Flush();
         }
 
-        public static void WriteTo(this IMessage message, ICodedOutputStream output)
+        public static void WriteTo(this IMessage message, CodedOutputStream output)
         {
             message.WriteTo(output);
         }
diff --git a/csharp/src/ProtocolBuffers/ICodedInputStream.cs b/csharp/src/ProtocolBuffers/ICodedInputStream.cs
deleted file mode 100644
index d962e62..0000000
--- a/csharp/src/ProtocolBuffers/ICodedInputStream.cs
+++ /dev/null
@@ -1,293 +0,0 @@
-#region Copyright notice and license

-

-// Protocol Buffers - Google's data interchange format

-// Copyright 2008 Google Inc.  All rights reserved.

-// http://github.com/jskeet/dotnet-protobufs/

-// Original C++/Java/Python code:

-// 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.

-

-#endregion

-

-using System;

-using System.Collections.Generic;

-using Google.Protobuf.Descriptors;

-

-//Disable warning CS3010: CLS-compliant interfaces must have only CLS-compliant members

-#pragma warning disable 3010

-

-namespace Google.Protobuf

-{

-    public interface ICodedInputStream

-    {

-        /// <summary>

-        /// Reads any message initialization data expected from the input stream

-        /// </summary>

-        /// <remarks>

-        /// This is primarily used by text formats and unnecessary for protobuffers' own

-        /// binary format.  The API for MessageStart/End was added for consistent handling

-        /// of output streams regardless of the actual writer implementation.

-        /// </remarks>

-        void ReadMessageStart();

-        /// <summary>

-        /// Reads any message finalization data expected from the input stream

-        /// </summary>

-        /// <remarks>

-        /// This is primarily used by text formats and unnecessary for protobuffers' own

-        /// binary format.  The API for MessageStart/End was added for consistent handling

-        /// of output streams regardless of the actual writer implementation.

-        /// </remarks>

-        void ReadMessageEnd();

-        /// <summary>

-        /// Attempt to read a field tag, returning false if we have reached the end

-        /// of the input data.

-        /// </summary>

-        /// <remarks>

-        /// <para>

-        /// If fieldTag is non-zero and ReadTag returns true then the value in fieldName

-        /// may or may not be populated.  However, if fieldTag is zero and ReadTag returns

-        /// true, then fieldName should be populated with a non-null field name.

-        /// </para><para>

-        /// In other words if ReadTag returns true then either fieldTag will be non-zero OR

-        /// fieldName will be non-zero.  In some cases both may be populated, however the

-        /// builders will always prefer the fieldTag over fieldName.

-        /// </para>

-        /// </remarks>

-        bool ReadTag(out uint fieldTag, out string fieldName);

-

-        /// <summary>

-        /// Read a double field from the stream.

-        /// </summary>

-        bool ReadDouble(ref double value);

-

-        /// <summary>

-        /// Read a float field from the stream.

-        /// </summary>

-        bool ReadFloat(ref float value);

-

-        /// <summary>

-        /// Read a uint64 field from the stream.

-        /// </summary>

-        bool ReadUInt64(ref ulong value);

-

-        /// <summary>

-        /// Read an int64 field from the stream.

-        /// </summary>

-        bool ReadInt64(ref long value);

-

-        /// <summary>

-        /// Read an int32 field from the stream.

-        /// </summary>

-        bool ReadInt32(ref int value);

-

-        /// <summary>

-        /// Read a fixed64 field from the stream.

-        /// </summary>

-        bool ReadFixed64(ref ulong value);

-

-        /// <summary>

-        /// Read a fixed32 field from the stream.

-        /// </summary>

-        bool ReadFixed32(ref uint value);

-

-        /// <summary>

-        /// Read a bool field from the stream.

-        /// </summary>

-        bool ReadBool(ref bool value);

-

-        /// <summary>

-        /// Reads a string field from the stream.

-        /// </summary>

-        bool ReadString(ref string value);

-

-        /// <summary>

-        /// Reads a group field value from the stream.

-        /// </summary>    

-        void ReadGroup(int fieldNumber, IMessage message);

-

-        /// <summary>

-        /// Reads an embedded message field value from the stream.

-        /// </summary>   

-        void ReadMessage(IMessage message);

-

-        /// <summary>

-        /// Reads a bytes field value from the stream.

-        /// </summary>   

-        bool ReadBytes(ref ByteString value);

-

-        /// <summary>

-        /// Reads a uint32 field value from the stream.

-        /// </summary>   

-        bool ReadUInt32(ref uint value);

-

-        /// <summary>

-        /// Reads an enum field value from the stream. This performs no checking

-        /// as to whether the enum value is known to the enum type as it was present

-        /// when the code was generated.

-        /// </summary>   

-        bool ReadEnum(ref int value);

-

-        /// <summary>

-        /// Reads an sfixed32 field value from the stream.

-        /// </summary>   

-        bool ReadSFixed32(ref int value);

-

-        /// <summary>

-        /// Reads an sfixed64 field value from the stream.

-        /// </summary>   

-        bool ReadSFixed64(ref long value);

-

-        /// <summary>

-        /// Reads an sint32 field value from the stream.

-        /// </summary>   

-        bool ReadSInt32(ref int value);

-

-        /// <summary>

-        /// Reads an sint64 field value from the stream.

-        /// </summary>   

-        bool ReadSInt64(ref long value);

-

-        /// <summary>

-        /// Reads an array of primitive values into the list, if the wire-type of fieldTag is length-prefixed and the 

-        /// type is numeric, it will read a packed array.

-        /// </summary>

-        void ReadPrimitiveArray(FieldType fieldType, uint fieldTag, string fieldName, ICollection<object> list);

-

-        /// <summary>

-        /// Reads an array of primitive values into the list, if the wire-type of fieldTag is length-prefixed, it will

-        /// read a packed array.

-        /// </summary>

-        void ReadEnumArray<T>(uint fieldTag, string fieldName, ICollection<T> list)

-            where T : struct, IComparable, IFormattable;

-

-        /// <summary>

-        /// Reads a set of messages using the <paramref name="parser"/> to read individual messages.

-        /// </summary>

-        void ReadMessageArray<T>(uint fieldTag, string fieldName, ICollection<T> list, MessageParser<T> parser) where T : IMessage<T>;

-

-        /// <summary>

-        /// Reads a set of messages using the <paramref name="parser"/> as a template.

-        /// </summary>

-        void ReadGroupArray<T>(uint fieldTag, string fieldName, ICollection<T> list, MessageParser<T> parser) where T : IMessage<T>;

-

-        /// <summary>

-        /// Reads a field of any primitive type. Enums, groups and embedded

-        /// messages are not handled by this method.

-        /// </summary>

-        bool ReadPrimitiveField(FieldType fieldType, ref object value);

-

-        /// <summary>

-        /// 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

-        /// the stream has reached a limit created using PushLimit.

-        /// </summary>

-        bool IsAtEnd { get; }

-

-        /// <summary>

-        /// Reads and discards a single field, given its tag value.

-        /// </summary>

-        /// <returns>false if the tag is an end-group tag, in which case

-        /// nothing is skipped. Otherwise, returns true.</returns>

-        bool SkipField();

-

-        /// <summary>

-        /// Reads one or more repeated string field values from the stream.

-        /// </summary>   

-        void ReadStringArray(uint fieldTag, string fieldName, ICollection<string> list);

-

-        /// <summary>

-        /// Reads one or more repeated ByteString field values from the stream.

-        /// </summary>   

-        void ReadBytesArray(uint fieldTag, string fieldName, ICollection<ByteString> list);

-

-        /// <summary>

-        /// Reads one or more repeated boolean field values from the stream.

-        /// </summary>

-        void ReadBoolArray(uint fieldTag, string fieldName, ICollection<bool> list);

-

-        /// <summary>

-        /// Reads one or more repeated Int32 field values from the stream.

-        /// </summary>

-        void ReadInt32Array(uint fieldTag, string fieldName, ICollection<int> list);

-

-        /// <summary>

-        /// Reads one or more repeated SInt32 field values from the stream.

-        /// </summary>

-        void ReadSInt32Array(uint fieldTag, string fieldName, ICollection<int> list);

-

-        /// <summary>

-        /// Reads one or more repeated UInt32 field values from the stream.

-        /// </summary>

-        void ReadUInt32Array(uint fieldTag, string fieldName, ICollection<uint> list);

-

-        /// <summary>

-        /// Reads one or more repeated Fixed32 field values from the stream.

-        /// </summary>

-        void ReadFixed32Array(uint fieldTag, string fieldName, ICollection<uint> list);

-

-        /// <summary>

-        /// Reads one or more repeated SFixed32 field values from the stream.

-        /// </summary>

-        void ReadSFixed32Array(uint fieldTag, string fieldName, ICollection<int> list);

-

-        /// <summary>

-        /// Reads one or more repeated Int64 field values from the stream.

-        /// </summary>

-        void ReadInt64Array(uint fieldTag, string fieldName, ICollection<long> list);

-

-        /// <summary>

-        /// Reads one or more repeated SInt64 field values from the stream.

-        /// </summary>

-        void ReadSInt64Array(uint fieldTag, string fieldName, ICollection<long> list);

-

-        /// <summary>

-        /// Reads one or more repeated UInt64 field values from the stream.

-        /// </summary>

-        void ReadUInt64Array(uint fieldTag, string fieldName, ICollection<ulong> list);

-

-        /// <summary>

-        /// Reads one or more repeated Fixed64 field values from the stream.

-        /// </summary>

-        void ReadFixed64Array(uint fieldTag, string fieldName, ICollection<ulong> list);

-

-        /// <summary>

-        /// Reads one or more repeated SFixed64 field values from the stream.

-        /// </summary>

-        void ReadSFixed64Array(uint fieldTag, string fieldName, ICollection<long> list);

-

-        /// <summary>

-        /// Reads one or more repeated Double field values from the stream.

-        /// </summary>

-        void ReadDoubleArray(uint fieldTag, string fieldName, ICollection<double> list);

-

-        /// <summary>

-        /// Reads one or more repeated Float field values from the stream.

-        /// </summary>

-        void ReadFloatArray(uint fieldTag, string fieldName, ICollection<float> list);

-    }

-}
\ No newline at end of file
diff --git a/csharp/src/ProtocolBuffers/ICodedOutputStream.cs b/csharp/src/ProtocolBuffers/ICodedOutputStream.cs
deleted file mode 100644
index 921400a..0000000
--- a/csharp/src/ProtocolBuffers/ICodedOutputStream.cs
+++ /dev/null
@@ -1,347 +0,0 @@
-#region Copyright notice and license

-

-// Protocol Buffers - Google's data interchange format

-// Copyright 2008 Google Inc.  All rights reserved.

-// http://github.com/jskeet/dotnet-protobufs/

-// Original C++/Java/Python code:

-// 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.

-

-#endregion

-

-using System;

-using System.Collections;

-using Google.Protobuf.Collections;

-using Google.Protobuf.Descriptors;

-

-//Disable warning CS3010: CLS-compliant interfaces must have only CLS-compliant members

-#pragma warning disable 3010

-

-namespace Google.Protobuf

-{

-    /// <summary>

-    /// Provides an interface that is used write a message.  Most often proto buffers are written

-    /// in their binary form by creating a instance via the CodedOutputStream.CreateInstance

-    /// static factory.

-    /// </summary>

-    public interface ICodedOutputStream

-    {

-        /// <summary>

-        /// Writes any message initialization data needed to the output stream

-        /// </summary>

-        /// <remarks>

-        /// This is primarily used by text formats and unnecessary for protobuffers' own

-        /// binary format.  The API for MessageStart/End was added for consistent handling

-        /// of output streams regardless of the actual writer implementation.

-        /// </remarks>

-        void WriteMessageStart();

-        /// <summary>

-        /// Writes any message finalization data needed to the output stream

-        /// </summary>

-        /// <remarks>

-        /// This is primarily used by text formats and unnecessary for protobuffers' own

-        /// binary format.  The API for MessageStart/End was added for consistent handling

-        /// of output streams regardless of the actual writer implementation.

-        /// </remarks>

-        void WriteMessageEnd();

-

-        /// <summary>

-        /// Indicates that all temporary buffers be written to the final output.

-        /// </summary>

-        void Flush();

-

-        /// <summary>

-        /// Writes a field value, including tag, to the stream.

-        /// </summary>

-        void WriteField(FieldType fieldType, int fieldNumber, string fieldName, object value);

-

-        /// <summary>

-        /// Writes a double field value, including tag, to the stream.

-        /// </summary>

-        void WriteDouble(int fieldNumber, string fieldName, double value);

-

-        /// <summary>

-        /// Writes a float field value, including tag, to the stream.

-        /// </summary>

-        void WriteFloat(int fieldNumber, string fieldName, float value);

-

-        /// <summary>

-        /// Writes a uint64 field value, including tag, to the stream.

-        /// </summary>

-        void WriteUInt64(int fieldNumber, string fieldName, ulong value);

-

-        /// <summary>

-        /// Writes an int64 field value, including tag, to the stream.

-        /// </summary>

-        void WriteInt64(int fieldNumber, string fieldName, long value);

-

-        /// <summary>

-        /// Writes an int32 field value, including tag, to the stream.

-        /// </summary>

-        void WriteInt32(int fieldNumber, string fieldName, int value);

-

-        /// <summary>

-        /// Writes a fixed64 field value, including tag, to the stream.

-        /// </summary>

-        void WriteFixed64(int fieldNumber, string fieldName, ulong value);

-

-        /// <summary>

-        /// Writes a fixed32 field value, including tag, to the stream.

-        /// </summary>

-        void WriteFixed32(int fieldNumber, string fieldName, uint value);

-

-        /// <summary>

-        /// Writes a bool field value, including tag, to the stream.

-        /// </summary>

-        void WriteBool(int fieldNumber, string fieldName, bool value);

-

-        /// <summary>

-        /// Writes a string field value, including tag, to the stream.

-        /// </summary>

-        void WriteString(int fieldNumber, string fieldName, string value);

-

-        /// <summary>

-        /// Writes a group field value, including tag, to the stream.

-        /// </summary>

-        void WriteGroup(int fieldNumber, string fieldName, IMessage value);

-

-        /// <summary>

-        /// Writes a message field value, including tag, to the stream.

-        /// </summary>

-        void WriteMessage(int fieldNumber, string fieldName, IMessage value);

-

-        /// <summary>

-        /// Writes a byte array field value, including tag, to the stream.

-        /// </summary>

-        void WriteBytes(int fieldNumber, string fieldName, ByteString value);

-

-        /// <summary>

-        /// Writes a UInt32 field value, including tag, to the stream.

-        /// </summary>

-        void WriteUInt32(int fieldNumber, string fieldName, uint value);

-

-        /// <summary>

-        /// Writes an enum field value, including tag, to the stream.

-        /// </summary>

-        void WriteEnum(int fieldNumber, string fieldName, int value);

-

-        /// <summary>

-        /// Writes a fixed 32-bit field value, including tag, to the stream.

-        /// </summary>

-        void WriteSFixed32(int fieldNumber, string fieldName, int value);

-

-        /// <summary>

-        /// Writes a signed fixed 64-bit field value, including tag, to the stream.

-        /// </summary>

-        void WriteSFixed64(int fieldNumber, string fieldName, long value);

-

-        /// <summary>

-        /// Writes a signed 32-bit field value, including tag, to the stream.

-        /// </summary>

-        void WriteSInt32(int fieldNumber, string fieldName, int value);

-

-        /// <summary>

-        /// Writes a signed 64-bit field value, including tag, to the stream.

-        /// </summary>

-        void WriteSInt64(int fieldNumber, string fieldName, long value);

-

-        /// <summary>

-        /// Writes a repeated field value, including tag(s), to the stream.

-        /// </summary>

-        void WriteArray(FieldType fieldType, int fieldNumber, string fieldName, IEnumerable list);

-

-        /// <summary>

-        /// Writes a repeated group value, including tag(s), to the stream.

-        /// </summary>

-        void WriteGroupArray<T>(int fieldNumber, string fieldName, RepeatedField<T> list)

-            where T : IMessage;

-

-        /// <summary>

-        /// Writes a repeated message value, including tag(s), to the stream.

-        /// </summary>

-        void WriteMessageArray<T>(int fieldNumber, string fieldName, RepeatedField<T> list)

-            where T : IMessage;

-

-        /// <summary>

-        /// Writes a repeated string value, including tag(s), to the stream.

-        /// </summary>

-        void WriteStringArray(int fieldNumber, string fieldName, RepeatedField<string> list);

-

-        /// <summary>

-        /// Writes a repeated ByteString value, including tag(s), to the stream.

-        /// </summary>

-        void WriteBytesArray(int fieldNumber, string fieldName, RepeatedField<ByteString> list);

-

-        /// <summary>

-        /// Writes a repeated boolean value, including tag(s), to the stream.

-        /// </summary>

-        void WriteBoolArray(int fieldNumber, string fieldName, RepeatedField<bool> list);

-

-        /// <summary>

-        /// Writes a repeated Int32 value, including tag(s), to the stream.

-        /// </summary>

-        void WriteInt32Array(int fieldNumber, string fieldName, RepeatedField<int> list);

-

-        /// <summary>

-        /// Writes a repeated SInt32 value, including tag(s), to the stream.

-        /// </summary>

-        void WriteSInt32Array(int fieldNumber, string fieldName, RepeatedField<int> list);

-

-        /// <summary>

-        /// Writes a repeated UInt32 value, including tag(s), to the stream.

-        /// </summary>

-        void WriteUInt32Array(int fieldNumber, string fieldName, RepeatedField<uint> list);

-

-        /// <summary>

-        /// Writes a repeated Fixed32 value, including tag(s), to the stream.

-        /// </summary>

-        void WriteFixed32Array(int fieldNumber, string fieldName, RepeatedField<uint> list);

-

-        /// <summary>

-        /// Writes a repeated SFixed32 value, including tag(s), to the stream.

-        /// </summary>

-        void WriteSFixed32Array(int fieldNumber, string fieldName, RepeatedField<int> list);

-

-        /// <summary>

-        /// Writes a repeated Int64 value, including tag(s), to the stream.

-        /// </summary>

-        void WriteInt64Array(int fieldNumber, string fieldName, RepeatedField<long> list);

-

-        /// <summary>

-        /// Writes a repeated SInt64 value, including tag(s), to the stream.

-        /// </summary>

-        void WriteSInt64Array(int fieldNumber, string fieldName, RepeatedField<long> list);

-

-        /// <summary>

-        /// Writes a repeated UInt64 value, including tag(s), to the stream.

-        /// </summary>

-        void WriteUInt64Array(int fieldNumber, string fieldName, RepeatedField<ulong> list);

-

-        /// <summary>

-        /// Writes a repeated Fixed64 value, including tag(s), to the stream.

-        /// </summary>

-        void WriteFixed64Array(int fieldNumber, string fieldName, RepeatedField<ulong> list);

-

-        /// <summary>

-        /// Writes a repeated SFixed64 value, including tag(s), to the stream.

-        /// </summary>

-        void WriteSFixed64Array(int fieldNumber, string fieldName, RepeatedField<long> list);

-

-        /// <summary>

-        /// Writes a repeated Double value, including tag(s), to the stream.

-        /// </summary>

-        void WriteDoubleArray(int fieldNumber, string fieldName, RepeatedField<double> list);

-

-        /// <summary>

-        /// Writes a repeated Float value, including tag(s), to the stream.

-        /// </summary>

-        void WriteFloatArray(int fieldNumber, string fieldName, RepeatedField<float> list);

-

-        /// <summary>

-        /// Writes a repeated enumeration value of type T, including tag(s), to the stream.

-        /// </summary>

-        void WriteEnumArray<T>(int fieldNumber, string fieldName, RepeatedField<T> list)

-            where T : struct, IComparable, IFormattable;

-

-        /// <summary>

-        /// Writes a packed repeated primitive, including tag and length, to the stream.

-        /// </summary>

-        void WritePackedArray(FieldType fieldType, int fieldNumber, string fieldName, IEnumerable list);

-

-        /// <summary>

-        /// Writes a packed repeated boolean, including tag and length, to the stream.

-        /// </summary>

-        void WritePackedBoolArray(int fieldNumber, string fieldName, RepeatedField<bool> list);

-

-        /// <summary>

-        /// Writes a packed repeated Int32, including tag and length, to the stream.

-        /// </summary>

-        void WritePackedInt32Array(int fieldNumber, string fieldName, RepeatedField<int> list);

-

-        /// <summary>

-        /// Writes a packed repeated SInt32, including tag and length, to the stream.

-        /// </summary>

-        void WritePackedSInt32Array(int fieldNumber, string fieldName, RepeatedField<int> list);

-

-        /// <summary>

-        /// Writes a packed repeated UInt32, including tag and length, to the stream.

-        /// </summary>

-        void WritePackedUInt32Array(int fieldNumber, string fieldName, RepeatedField<uint> list);

-

-        /// <summary>

-        /// Writes a packed repeated Fixed32, including tag and length, to the stream.

-        /// </summary>

-        void WritePackedFixed32Array(int fieldNumber, string fieldName, RepeatedField<uint> list);

-

-        /// <summary>

-        /// Writes a packed repeated SFixed32, including tag and length, to the stream.

-        /// </summary>

-        void WritePackedSFixed32Array(int fieldNumber, string fieldName, RepeatedField<int> list);

-

-        /// <summary>

-        /// Writes a packed repeated Int64, including tag and length, to the stream.

-        /// </summary>

-        void WritePackedInt64Array(int fieldNumber, string fieldName, RepeatedField<long> list);

-

-        /// <summary>

-        /// Writes a packed repeated SInt64, including tag and length, to the stream.

-        /// </summary>

-        void WritePackedSInt64Array(int fieldNumber, string fieldName, RepeatedField<long> list);

-

-        /// <summary>

-        /// Writes a packed repeated UInt64, including tag and length, to the stream.

-        /// </summary>

-        void WritePackedUInt64Array(int fieldNumber, string fieldName, RepeatedField<ulong> list);

-

-        /// <summary>

-        /// Writes a packed repeated Fixed64, including tag and length, to the stream.

-        /// </summary>

-        void WritePackedFixed64Array(int fieldNumber, string fieldName, RepeatedField<ulong> list);

-

-        /// <summary>

-        /// Writes a packed repeated SFixed64, including tag and length, to the stream.

-        /// </summary>

-        void WritePackedSFixed64Array(int fieldNumber, string fieldName, RepeatedField<long> list);

-

-        /// <summary>

-        /// Writes a packed repeated Double, including tag and length, to the stream.

-        /// </summary>

-        void WritePackedDoubleArray(int fieldNumber, string fieldName, RepeatedField<double> list);

-

-        /// <summary>

-        /// Writes a packed repeated Float, including tag and length, to the stream.

-        /// </summary>

-        void WritePackedFloatArray(int fieldNumber, string fieldName, RepeatedField<float> list);

-

-        /// <summary>

-        /// Writes a packed repeated enumeration of type T, including tag and length, to the stream.

-        /// </summary>

-        void WritePackedEnumArray<T>(int fieldNumber, string fieldName, RepeatedField<T> list)

-            where T : struct, IComparable, IFormattable;

-    }

-}
\ No newline at end of file
diff --git a/csharp/src/ProtocolBuffers/IMessage.cs b/csharp/src/ProtocolBuffers/IMessage.cs
index 4e06f6e..55b6fc5 100644
--- a/csharp/src/ProtocolBuffers/IMessage.cs
+++ b/csharp/src/ProtocolBuffers/IMessage.cs
@@ -51,8 +51,8 @@
 

     public interface IMessage

     {

-        void MergeFrom(ICodedInputStream input);

-        void WriteTo(ICodedOutputStream output);

+        void MergeFrom(CodedInputStream input);

+        void WriteTo(CodedOutputStream output);

         int CalculateSize();

     }

 

diff --git a/csharp/src/ProtocolBuffers/MessageParser.cs b/csharp/src/ProtocolBuffers/MessageParser.cs
index 399a904..722435c 100644
--- a/csharp/src/ProtocolBuffers/MessageParser.cs
+++ b/csharp/src/ProtocolBuffers/MessageParser.cs
@@ -47,7 +47,7 @@
             return message;
         }
 
-        public T ParseFrom(ICodedInputStream input)
+        public T ParseFrom(CodedInputStream input)
         {
             T message = factory();
             message.MergeFrom(input);
diff --git a/csharp/src/ProtocolBuffers/ProtocolBuffers.csproj b/csharp/src/ProtocolBuffers/ProtocolBuffers.csproj
index efd387a..3a07e87 100644
--- a/csharp/src/ProtocolBuffers/ProtocolBuffers.csproj
+++ b/csharp/src/ProtocolBuffers/ProtocolBuffers.csproj
@@ -93,8 +93,6 @@
     <Compile Include="FieldAccess\FieldAccessorTable.cs" />

     <Compile Include="FieldAccess\OneofAccessor.cs" />

     <Compile Include="FrameworkPortability.cs" />

-    <Compile Include="ICodedInputStream.cs" />

-    <Compile Include="ICodedOutputStream.cs" />

     <Compile Include="IMessage.cs" />

     <Compile Include="InvalidProtocolBufferException.cs" />

     <Compile Include="LimitedInputStream.cs" />

diff --git a/src/google/protobuf/compiler/csharp/csharp_enum_field.cc b/src/google/protobuf/compiler/csharp/csharp_enum_field.cc
index 3494b22..19fd50c 100644
--- a/src/google/protobuf/compiler/csharp/csharp_enum_field.cc
+++ b/src/google/protobuf/compiler/csharp/csharp_enum_field.cc
@@ -54,17 +54,14 @@
 }
 
 void EnumFieldGenerator::GenerateParsingCode(io::Printer* printer) {
-  // TODO(jonskeet): Get rid of the temporary variable when we sanitize CodedInputStream not to use ref.
   printer->Print(variables_,
-    "int tmp = 0;\n"
-    "input.ReadEnum(ref tmp);\n"
-    "$name$_ = ($type_name$) tmp;");
+    "$name$_ = ($type_name$) input.ReadEnum();\n");
 }
 
 void EnumFieldGenerator::GenerateSerializationCode(io::Printer* printer) {
   printer->Print(variables_,
     "if ($has_property_check$) {\n"
-    "  output.WriteEnum($number$, fieldNames[$field_ordinal$], (int) $property_name$);\n"
+    "  output.WriteEnum($number$, (int) $property_name$);\n"
     "}\n");
 }
 
@@ -88,18 +85,15 @@
   // TODO(jonskeet): What about if we read the default value?
   printer->Print(
     variables_,
-    "int enumValue = 0;\n"
-    "if(input.ReadEnum(ref enumValue)) {\n"
-    "  $oneof_name$_ = enumValue;\n"
-    "  $oneof_name$Case_ = $oneof_property_name$OneofCase.$property_name$;\n"
-    "}\n");
+    "$oneof_name$_ = input.ReadEnum();\n"
+    "$oneof_name$Case_ = $oneof_property_name$OneofCase.$property_name$;\n");
 }
 
 void EnumOneofFieldGenerator::GenerateSerializationCode(io::Printer* printer) {
   printer->Print(
     variables_,
     "if ($has_property_check$) {\n"
-    "  output.WriteEnum($number$, fieldNames[$field_ordinal$], (int) $property_name$);\n"
+    "  output.WriteEnum($number$, (int) $property_name$);\n"
     "}\n");
 }
 
diff --git a/src/google/protobuf/compiler/csharp/csharp_message.cc b/src/google/protobuf/compiler/csharp/csharp_message.cc
index b5929bc..aca68fb 100644
--- a/src/google/protobuf/compiler/csharp/csharp_message.cc
+++ b/src/google/protobuf/compiler/csharp/csharp_message.cc
@@ -350,9 +350,8 @@
 
 void MessageGenerator::GenerateMessageSerializationMethods(io::Printer* printer) {
   printer->Print(
-      "public void WriteTo(pb::ICodedOutputStream output) {\n");
+      "public void WriteTo(pb::CodedOutputStream output) {\n");
   printer->Indent();
-  printer->Print("string[] fieldNames = _fieldNames;\n");
 
   // Serialize all the fields
   for (int i = 0; i < fields_by_number().size(); i++) {
@@ -423,21 +422,13 @@
   }
   printer->Outdent();
   printer->Print("}\n\n");
-  printer->Print("public void MergeFrom(pb::ICodedInputStream input) {\n");
+  printer->Print("public void MergeFrom(pb::CodedInputStream input) {\n");
   printer->Indent();
   printer->Print(
     "uint tag;\n"
-    "string fieldName;\n"
-    "while (input.ReadTag(out tag, out fieldName)) {\n");
+    "while (input.ReadTag(out tag)) {\n"
+    "  switch(tag) {\n");
   printer->Indent();
-  printer->Print(
-    "if (tag == 0 && fieldName != null) {\n"
-    "  int fieldOrdinal = global::System.Array.BinarySearch(_fieldNames, fieldName, global::System.StringComparer.Ordinal);\n"
-    "  if (fieldOrdinal >= 0) {\n"
-    "    tag = _fieldTags[fieldOrdinal];\n"
-    "  }\n"
-    "}\n"
-    "switch(tag) {\n");
   printer->Indent();
   printer->Print(
     "case 0:\n"  // 0 signals EOF / limit reached
diff --git a/src/google/protobuf/compiler/csharp/csharp_message_field.cc b/src/google/protobuf/compiler/csharp/csharp_message_field.cc
index 4b7ac88..804a5ae 100644
--- a/src/google/protobuf/compiler/csharp/csharp_message_field.cc
+++ b/src/google/protobuf/compiler/csharp/csharp_message_field.cc
@@ -87,6 +87,7 @@
     "if ($has_not_property_check$) {\n"
     "  $name$_ = new $type_name$();\n"
     "}\n"
+    // TODO(jonskeet): Do we really need merging behaviour like this?
     "input.ReadMessage($name$_);\n"); // No need to support TYPE_GROUP...
 }
 
@@ -95,7 +96,7 @@
   printer->Print(
     variables_,
     "if ($has_property_check$) {\n"
-    "  output.WriteMessage($number$, fieldNames[$field_ordinal$], $property_name$);\n"
+    "  output.WriteMessage($number$, $property_name$);\n"
     "}\n");
 }
 
diff --git a/src/google/protobuf/compiler/csharp/csharp_primitive_field.cc b/src/google/protobuf/compiler/csharp/csharp_primitive_field.cc
index f2b66a0..cb7e1b5 100644
--- a/src/google/protobuf/compiler/csharp/csharp_primitive_field.cc
+++ b/src/google/protobuf/compiler/csharp/csharp_primitive_field.cc
@@ -73,7 +73,6 @@
     printer->Print(
       variables_,
       "  set { $name$_ = value; }\n");
-
   } else {
     printer->Print(
       variables_,
@@ -93,14 +92,14 @@
 void PrimitiveFieldGenerator::GenerateParsingCode(io::Printer* printer) {
   printer->Print(
     variables_,
-    "input.Read$capitalized_type_name$(ref $name$_);\n");
+    "$name$_ = input.Read$capitalized_type_name$();\n");
 }
 
 void PrimitiveFieldGenerator::GenerateSerializationCode(io::Printer* printer) {
   printer->Print(
     variables_,
     "if ($has_property_check$) {\n"
-    "  output.Write$capitalized_type_name$($number$, fieldNames[$field_ordinal$], $property_name$);\n"
+    "  output.Write$capitalized_type_name$($number$, $property_name$);\n"
     "}\n");
 }
 
@@ -169,13 +168,10 @@
 
 void PrimitiveOneofFieldGenerator::GenerateParsingCode(io::Printer* printer) {
   // TODO(jonskeet): What if the value we read is the default value for the type?
-  printer->Print(
-    variables_,
-    "$type_name$ value = $default_value$;\n"
-    "if (input.Read$capitalized_type_name$(ref value)) {\n"
-    "  $oneof_name$_ = value;\n"
-    "  $oneof_name$Case_ = $oneof_property_name$OneofCase.$property_name$;\n"
-    "}\n");
+    printer->Print(
+      variables_,
+      "$oneof_name$_ = input.Read$capitalized_type_name$()\n;"
+      "$oneof_name$Case_ = $oneof_property_name$OneofCase.$property_name$;\n");
 }
 
 }  // namespace csharp
diff --git a/src/google/protobuf/compiler/csharp/csharp_repeated_enum_field.cc b/src/google/protobuf/compiler/csharp/csharp_repeated_enum_field.cc
index 937d675..15e92ab 100644
--- a/src/google/protobuf/compiler/csharp/csharp_repeated_enum_field.cc
+++ b/src/google/protobuf/compiler/csharp/csharp_repeated_enum_field.cc
@@ -76,7 +76,7 @@
 void RepeatedEnumFieldGenerator::GenerateParsingCode(io::Printer* printer) {
   printer->Print(
     variables_,
-    "input.ReadEnumArray<$type_name$>(tag, fieldName, $name$_);\n");
+    "input.ReadEnumArray<$type_name$>(tag, $name$_);\n");
 }
 
 void RepeatedEnumFieldGenerator::GenerateSerializationCode(io::Printer* printer) {
@@ -84,7 +84,7 @@
   // The Write* call should make that cheap though - no need to generate it every time.
   printer->Print(
     variables_,
-    "output.Write$packed$EnumArray($number$, fieldNames[$field_ordinal$], $name$_);\n");
+    "output.Write$packed$EnumArray($number$, $name$_);\n");
 }
 
 void RepeatedEnumFieldGenerator::GenerateSerializedSizeCode(io::Printer* printer) {
diff --git a/src/google/protobuf/compiler/csharp/csharp_repeated_message_field.cc b/src/google/protobuf/compiler/csharp/csharp_repeated_message_field.cc
index 963f841..6228aa6 100644
--- a/src/google/protobuf/compiler/csharp/csharp_repeated_message_field.cc
+++ b/src/google/protobuf/compiler/csharp/csharp_repeated_message_field.cc
@@ -75,7 +75,7 @@
 void RepeatedMessageFieldGenerator::GenerateParsingCode(io::Printer* printer) {
   printer->Print(
     variables_,
-    "input.ReadMessageArray(tag, fieldName, $name$_, $type_name$.Parser);\n");
+    "input.ReadMessageArray(tag, $name$_, $type_name$.Parser);\n");
 }
 
 void RepeatedMessageFieldGenerator::GenerateSerializationCode(io::Printer* printer) {
@@ -83,7 +83,7 @@
   // The Write* call should make that cheap though - no need to generate it every time.
   printer->Print(
     variables_,
-    "output.WriteMessageArray($number$, fieldNames[$field_ordinal$], $name$_);\n");
+    "output.WriteMessageArray($number$, $name$_);\n");
 }
 
 void RepeatedMessageFieldGenerator::GenerateSerializedSizeCode(io::Printer* printer) {
diff --git a/src/google/protobuf/compiler/csharp/csharp_repeated_primitive_field.cc b/src/google/protobuf/compiler/csharp/csharp_repeated_primitive_field.cc
index 0a91c3c..f62ea09 100644
--- a/src/google/protobuf/compiler/csharp/csharp_repeated_primitive_field.cc
+++ b/src/google/protobuf/compiler/csharp/csharp_repeated_primitive_field.cc
@@ -74,7 +74,7 @@
 
 void RepeatedPrimitiveFieldGenerator::GenerateParsingCode(io::Printer* printer) {
   printer->Print(variables_,
-    "input.Read$capitalized_type_name$Array(tag, fieldName, $name$_);\n");
+    "input.Read$capitalized_type_name$Array(tag, $name$_);\n");
 }
 
 void RepeatedPrimitiveFieldGenerator::GenerateSerializationCode(
@@ -83,10 +83,10 @@
   // The Write* call should make that cheap though - no need to generate it every time.
   if (descriptor_->is_packed()) {
     printer->Print(variables_,
-      "output.WritePacked$capitalized_type_name$Array($number$, fieldNames[$field_ordinal$], $name$_);\n");
+      "output.WritePacked$capitalized_type_name$Array($number$, $name$_);\n");
   } else {
     printer->Print(variables_,
-      "output.Write$capitalized_type_name$Array($number$, fieldNames[$field_ordinal$], $name$_);\n");
+      "output.Write$capitalized_type_name$Array($number$, $name$_);\n");
   }
 }