Avoid creating UnknownFieldSets unless we really have to.
diff --git a/src/AddressBook/AddressBookProtos.cs b/src/AddressBook/AddressBookProtos.cs
index 701e016..60f02d9 100644
--- a/src/AddressBook/AddressBookProtos.cs
+++ b/src/AddressBook/AddressBookProtos.cs
@@ -246,19 +246,27 @@
           }
           
           public override Builder MergeFrom(pb::CodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
-            pb::UnknownFieldSet.Builder unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+            pb::UnknownFieldSet.Builder unknownFields = null;
             while (true) {
               uint tag = input.ReadTag();
               switch (tag) {
                 case 0: {
-                  this.UnknownFields = unknownFields.Build();
+                  if (unknownFields != null) {
+                    this.UnknownFields = unknownFields.Build();
+                  }
                   return this;
                 }
                 default: {
-                  if (!ParseUnknownField(input, unknownFields, extensionRegistry, tag)) {
-                    this.UnknownFields = unknownFields.Build();
+                  if (pb::WireFormat.IsEndGroupTag(tag)) {
+                    if (unknownFields != null) {
+                      this.UnknownFields = unknownFields.Build();
+                    }
                     return this;
                   }
+                  if (unknownFields == null) {
+                    unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+                  }
+                  ParseUnknownField(input, unknownFields, extensionRegistry, tag);
                   break;
                 }
                 case 10: {
@@ -268,6 +276,9 @@
                 case 16: {
                   int rawValue = input.ReadEnum();
                   if (!global::System.Enum.IsDefined(typeof(global::Google.ProtocolBuffers.Examples.AddressBook.Person.Types.PhoneType), rawValue)) {
+                    if (unknownFields == null) {
+                      unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+                    }
                     unknownFields.MergeVarintField(2, (ulong) rawValue);
                   } else {
                     Type = (global::Google.ProtocolBuffers.Examples.AddressBook.Person.Types.PhoneType) rawValue;
@@ -510,19 +521,27 @@
       }
       
       public override Builder MergeFrom(pb::CodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
-        pb::UnknownFieldSet.Builder unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+        pb::UnknownFieldSet.Builder unknownFields = null;
         while (true) {
           uint tag = input.ReadTag();
           switch (tag) {
             case 0: {
-              this.UnknownFields = unknownFields.Build();
+              if (unknownFields != null) {
+                this.UnknownFields = unknownFields.Build();
+              }
               return this;
             }
             default: {
-              if (!ParseUnknownField(input, unknownFields, extensionRegistry, tag)) {
-                this.UnknownFields = unknownFields.Build();
+              if (pb::WireFormat.IsEndGroupTag(tag)) {
+                if (unknownFields != null) {
+                  this.UnknownFields = unknownFields.Build();
+                }
                 return this;
               }
+              if (unknownFields == null) {
+                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+              }
+              ParseUnknownField(input, unknownFields, extensionRegistry, tag);
               break;
             }
             case 10: {
@@ -799,19 +818,27 @@
       }
       
       public override Builder MergeFrom(pb::CodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
-        pb::UnknownFieldSet.Builder unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+        pb::UnknownFieldSet.Builder unknownFields = null;
         while (true) {
           uint tag = input.ReadTag();
           switch (tag) {
             case 0: {
-              this.UnknownFields = unknownFields.Build();
+              if (unknownFields != null) {
+                this.UnknownFields = unknownFields.Build();
+              }
               return this;
             }
             default: {
-              if (!ParseUnknownField(input, unknownFields, extensionRegistry, tag)) {
-                this.UnknownFields = unknownFields.Build();
+              if (pb::WireFormat.IsEndGroupTag(tag)) {
+                if (unknownFields != null) {
+                  this.UnknownFields = unknownFields.Build();
+                }
                 return this;
               }
+              if (unknownFields == null) {
+                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+              }
+              ParseUnknownField(input, unknownFields, extensionRegistry, tag);
               break;
             }
             case 10: {
diff --git a/src/ProtoGen/EnumFieldGenerator.cs b/src/ProtoGen/EnumFieldGenerator.cs
index 14c96da..aecf688 100644
--- a/src/ProtoGen/EnumFieldGenerator.cs
+++ b/src/ProtoGen/EnumFieldGenerator.cs
@@ -54,6 +54,9 @@
       // TODO(jonskeet): Make a more efficient way of doing this
       writer.WriteLine("int rawValue = input.ReadEnum();");
       writer.WriteLine("if (!global::System.Enum.IsDefined(typeof({0}), rawValue)) {{", TypeName);
+      writer.WriteLine("  if (unknownFields == null) {"); // First unknown field - create builder now
+      writer.WriteLine("    unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);");
+      writer.WriteLine("  }");
       writer.WriteLine("  unknownFields.MergeVarintField({0}, (ulong) rawValue);", Number);
       writer.WriteLine("} else {");
       writer.WriteLine("  {0} = ({1}) rawValue;", PropertyName, TypeName);
diff --git a/src/ProtoGen/MessageGenerator.cs b/src/ProtoGen/MessageGenerator.cs
index 63b8f32..dbeece7 100644
--- a/src/ProtoGen/MessageGenerator.cs
+++ b/src/ProtoGen/MessageGenerator.cs
@@ -374,21 +374,29 @@
       writer.WriteLine();
       writer.WriteLine("public override Builder MergeFrom(pb::CodedInputStream input, pb::ExtensionRegistry extensionRegistry) {");
       writer.Indent();
-      writer.WriteLine("pb::UnknownFieldSet.Builder unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);");
+      writer.WriteLine("pb::UnknownFieldSet.Builder unknownFields = null;");
       writer.WriteLine("while (true) {");
       writer.Indent();
       writer.WriteLine("uint tag = input.ReadTag();");
       writer.WriteLine("switch (tag) {");
       writer.Indent();
       writer.WriteLine("case 0: {"); // 0 signals EOF / limit reached
-      writer.WriteLine("  this.UnknownFields = unknownFields.Build();");
+      writer.WriteLine("  if (unknownFields != null) {");
+      writer.WriteLine("    this.UnknownFields = unknownFields.Build();");
+      writer.WriteLine("  }");
       writer.WriteLine("  return this;");
       writer.WriteLine("}");
       writer.WriteLine("default: {");
-      writer.WriteLine("  if (!ParseUnknownField(input, unknownFields, extensionRegistry, tag)) {");
-      writer.WriteLine("    this.UnknownFields = unknownFields.Build();");
+      writer.WriteLine("  if (pb::WireFormat.IsEndGroupTag(tag)) {");
+      writer.WriteLine("    if (unknownFields != null) {");
+      writer.WriteLine("      this.UnknownFields = unknownFields.Build();");
+      writer.WriteLine("    }");
       writer.WriteLine("    return this;"); // it's an endgroup tag
       writer.WriteLine("  }");
+      writer.WriteLine("  if (unknownFields == null) {"); // First unknown field - create builder now
+      writer.WriteLine("    unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);");
+      writer.WriteLine("  }");
+      writer.WriteLine("  ParseUnknownField(input, unknownFields, extensionRegistry, tag);");
       writer.WriteLine("  break;");
       writer.WriteLine("}");
       foreach (FieldDescriptor field in sortedFields) {
diff --git a/src/ProtoGen/RepeatedEnumFieldGenerator.cs b/src/ProtoGen/RepeatedEnumFieldGenerator.cs
index 1bd6c00..473970f 100644
--- a/src/ProtoGen/RepeatedEnumFieldGenerator.cs
+++ b/src/ProtoGen/RepeatedEnumFieldGenerator.cs
@@ -79,11 +79,14 @@
       // TODO(jonskeet): Make a more efficient way of doing this
       writer.WriteLine("int rawValue = input.ReadEnum();");
       writer.WriteLine("if (!global::System.Enum.IsDefined(typeof({0}), rawValue)) {{", TypeName);
+      writer.WriteLine("  if (unknownFields == null) {"); // First unknown field - create builder now
+      writer.WriteLine("    unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);");
+      writer.WriteLine("  }");
       writer.WriteLine("  unknownFields.MergeVarintField({0}, (ulong) rawValue);", Number);
       writer.WriteLine("} else {");
       writer.WriteLine("  Add{0}(({1}) rawValue);", PropertyName, TypeName);
       writer.WriteLine("}");
-
+      
       if (Descriptor.IsPacked) {
         writer.Outdent();
         writer.WriteLine("}");
diff --git a/src/ProtocolBuffers.Test/TestProtos/UnitTestEmbedOptimizeForProtoFile.cs b/src/ProtocolBuffers.Test/TestProtos/UnitTestEmbedOptimizeForProtoFile.cs
index 8aca399..1e089c0 100644
--- a/src/ProtocolBuffers.Test/TestProtos/UnitTestEmbedOptimizeForProtoFile.cs
+++ b/src/ProtocolBuffers.Test/TestProtos/UnitTestEmbedOptimizeForProtoFile.cs
@@ -214,19 +214,27 @@
       }
       
       public override Builder MergeFrom(pb::CodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
-        pb::UnknownFieldSet.Builder unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+        pb::UnknownFieldSet.Builder unknownFields = null;
         while (true) {
           uint tag = input.ReadTag();
           switch (tag) {
             case 0: {
-              this.UnknownFields = unknownFields.Build();
+              if (unknownFields != null) {
+                this.UnknownFields = unknownFields.Build();
+              }
               return this;
             }
             default: {
-              if (!ParseUnknownField(input, unknownFields, extensionRegistry, tag)) {
-                this.UnknownFields = unknownFields.Build();
+              if (pb::WireFormat.IsEndGroupTag(tag)) {
+                if (unknownFields != null) {
+                  this.UnknownFields = unknownFields.Build();
+                }
                 return this;
               }
+              if (unknownFields == null) {
+                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+              }
+              ParseUnknownField(input, unknownFields, extensionRegistry, tag);
               break;
             }
             case 10: {
diff --git a/src/ProtocolBuffers.Test/TestProtos/UnitTestImportProtoFile.cs b/src/ProtocolBuffers.Test/TestProtos/UnitTestImportProtoFile.cs
index 9b5f828..c2ec69c 100644
--- a/src/ProtocolBuffers.Test/TestProtos/UnitTestImportProtoFile.cs
+++ b/src/ProtocolBuffers.Test/TestProtos/UnitTestImportProtoFile.cs
@@ -193,19 +193,27 @@
       }
       
       public override Builder MergeFrom(pb::CodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
-        pb::UnknownFieldSet.Builder unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+        pb::UnknownFieldSet.Builder unknownFields = null;
         while (true) {
           uint tag = input.ReadTag();
           switch (tag) {
             case 0: {
-              this.UnknownFields = unknownFields.Build();
+              if (unknownFields != null) {
+                this.UnknownFields = unknownFields.Build();
+              }
               return this;
             }
             default: {
-              if (!ParseUnknownField(input, unknownFields, extensionRegistry, tag)) {
-                this.UnknownFields = unknownFields.Build();
+              if (pb::WireFormat.IsEndGroupTag(tag)) {
+                if (unknownFields != null) {
+                  this.UnknownFields = unknownFields.Build();
+                }
                 return this;
               }
+              if (unknownFields == null) {
+                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+              }
+              ParseUnknownField(input, unknownFields, extensionRegistry, tag);
               break;
             }
             case 8: {
diff --git a/src/ProtocolBuffers.Test/TestProtos/UnitTestMessageSetProtoFile.cs b/src/ProtocolBuffers.Test/TestProtos/UnitTestMessageSetProtoFile.cs
index e97b27a..026d9e8 100644
--- a/src/ProtocolBuffers.Test/TestProtos/UnitTestMessageSetProtoFile.cs
+++ b/src/ProtocolBuffers.Test/TestProtos/UnitTestMessageSetProtoFile.cs
@@ -205,19 +205,27 @@
       }
       
       public override Builder MergeFrom(pb::CodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
-        pb::UnknownFieldSet.Builder unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+        pb::UnknownFieldSet.Builder unknownFields = null;
         while (true) {
           uint tag = input.ReadTag();
           switch (tag) {
             case 0: {
-              this.UnknownFields = unknownFields.Build();
+              if (unknownFields != null) {
+                this.UnknownFields = unknownFields.Build();
+              }
               return this;
             }
             default: {
-              if (!ParseUnknownField(input, unknownFields, extensionRegistry, tag)) {
-                this.UnknownFields = unknownFields.Build();
+              if (pb::WireFormat.IsEndGroupTag(tag)) {
+                if (unknownFields != null) {
+                  this.UnknownFields = unknownFields.Build();
+                }
                 return this;
               }
+              if (unknownFields == null) {
+                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+              }
+              ParseUnknownField(input, unknownFields, extensionRegistry, tag);
               break;
             }
           }
@@ -376,19 +384,27 @@
       }
       
       public override Builder MergeFrom(pb::CodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
-        pb::UnknownFieldSet.Builder unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+        pb::UnknownFieldSet.Builder unknownFields = null;
         while (true) {
           uint tag = input.ReadTag();
           switch (tag) {
             case 0: {
-              this.UnknownFields = unknownFields.Build();
+              if (unknownFields != null) {
+                this.UnknownFields = unknownFields.Build();
+              }
               return this;
             }
             default: {
-              if (!ParseUnknownField(input, unknownFields, extensionRegistry, tag)) {
-                this.UnknownFields = unknownFields.Build();
+              if (pb::WireFormat.IsEndGroupTag(tag)) {
+                if (unknownFields != null) {
+                  this.UnknownFields = unknownFields.Build();
+                }
                 return this;
               }
+              if (unknownFields == null) {
+                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+              }
+              ParseUnknownField(input, unknownFields, extensionRegistry, tag);
               break;
             }
             case 10: {
@@ -594,19 +610,27 @@
       }
       
       public override Builder MergeFrom(pb::CodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
-        pb::UnknownFieldSet.Builder unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+        pb::UnknownFieldSet.Builder unknownFields = null;
         while (true) {
           uint tag = input.ReadTag();
           switch (tag) {
             case 0: {
-              this.UnknownFields = unknownFields.Build();
+              if (unknownFields != null) {
+                this.UnknownFields = unknownFields.Build();
+              }
               return this;
             }
             default: {
-              if (!ParseUnknownField(input, unknownFields, extensionRegistry, tag)) {
-                this.UnknownFields = unknownFields.Build();
+              if (pb::WireFormat.IsEndGroupTag(tag)) {
+                if (unknownFields != null) {
+                  this.UnknownFields = unknownFields.Build();
+                }
                 return this;
               }
+              if (unknownFields == null) {
+                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+              }
+              ParseUnknownField(input, unknownFields, extensionRegistry, tag);
               break;
             }
             case 120: {
@@ -789,19 +813,27 @@
       }
       
       public override Builder MergeFrom(pb::CodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
-        pb::UnknownFieldSet.Builder unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+        pb::UnknownFieldSet.Builder unknownFields = null;
         while (true) {
           uint tag = input.ReadTag();
           switch (tag) {
             case 0: {
-              this.UnknownFields = unknownFields.Build();
+              if (unknownFields != null) {
+                this.UnknownFields = unknownFields.Build();
+              }
               return this;
             }
             default: {
-              if (!ParseUnknownField(input, unknownFields, extensionRegistry, tag)) {
-                this.UnknownFields = unknownFields.Build();
+              if (pb::WireFormat.IsEndGroupTag(tag)) {
+                if (unknownFields != null) {
+                  this.UnknownFields = unknownFields.Build();
+                }
                 return this;
               }
+              if (unknownFields == null) {
+                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+              }
+              ParseUnknownField(input, unknownFields, extensionRegistry, tag);
               break;
             }
             case 202: {
@@ -1027,19 +1059,27 @@
           }
           
           public override Builder MergeFrom(pb::CodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
-            pb::UnknownFieldSet.Builder unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+            pb::UnknownFieldSet.Builder unknownFields = null;
             while (true) {
               uint tag = input.ReadTag();
               switch (tag) {
                 case 0: {
-                  this.UnknownFields = unknownFields.Build();
+                  if (unknownFields != null) {
+                    this.UnknownFields = unknownFields.Build();
+                  }
                   return this;
                 }
                 default: {
-                  if (!ParseUnknownField(input, unknownFields, extensionRegistry, tag)) {
-                    this.UnknownFields = unknownFields.Build();
+                  if (pb::WireFormat.IsEndGroupTag(tag)) {
+                    if (unknownFields != null) {
+                      this.UnknownFields = unknownFields.Build();
+                    }
                     return this;
                   }
+                  if (unknownFields == null) {
+                    unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+                  }
+                  ParseUnknownField(input, unknownFields, extensionRegistry, tag);
                   break;
                 }
                 case 16: {
@@ -1227,19 +1267,27 @@
       }
       
       public override Builder MergeFrom(pb::CodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
-        pb::UnknownFieldSet.Builder unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+        pb::UnknownFieldSet.Builder unknownFields = null;
         while (true) {
           uint tag = input.ReadTag();
           switch (tag) {
             case 0: {
-              this.UnknownFields = unknownFields.Build();
+              if (unknownFields != null) {
+                this.UnknownFields = unknownFields.Build();
+              }
               return this;
             }
             default: {
-              if (!ParseUnknownField(input, unknownFields, extensionRegistry, tag)) {
-                this.UnknownFields = unknownFields.Build();
+              if (pb::WireFormat.IsEndGroupTag(tag)) {
+                if (unknownFields != null) {
+                  this.UnknownFields = unknownFields.Build();
+                }
                 return this;
               }
+              if (unknownFields == null) {
+                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+              }
+              ParseUnknownField(input, unknownFields, extensionRegistry, tag);
               break;
             }
             case 11: {
diff --git a/src/ProtocolBuffers.Test/TestProtos/UnitTestProtoFile.cs b/src/ProtocolBuffers.Test/TestProtos/UnitTestProtoFile.cs
index d0394b8..59abd79 100644
--- a/src/ProtocolBuffers.Test/TestProtos/UnitTestProtoFile.cs
+++ b/src/ProtocolBuffers.Test/TestProtos/UnitTestProtoFile.cs
@@ -902,19 +902,27 @@
           }
           
           public override Builder MergeFrom(pb::CodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
-            pb::UnknownFieldSet.Builder unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+            pb::UnknownFieldSet.Builder unknownFields = null;
             while (true) {
               uint tag = input.ReadTag();
               switch (tag) {
                 case 0: {
-                  this.UnknownFields = unknownFields.Build();
+                  if (unknownFields != null) {
+                    this.UnknownFields = unknownFields.Build();
+                  }
                   return this;
                 }
                 default: {
-                  if (!ParseUnknownField(input, unknownFields, extensionRegistry, tag)) {
-                    this.UnknownFields = unknownFields.Build();
+                  if (pb::WireFormat.IsEndGroupTag(tag)) {
+                    if (unknownFields != null) {
+                      this.UnknownFields = unknownFields.Build();
+                    }
                     return this;
                   }
+                  if (unknownFields == null) {
+                    unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+                  }
+                  ParseUnknownField(input, unknownFields, extensionRegistry, tag);
                   break;
                 }
                 case 8: {
@@ -1095,19 +1103,27 @@
           }
           
           public override Builder MergeFrom(pb::CodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
-            pb::UnknownFieldSet.Builder unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+            pb::UnknownFieldSet.Builder unknownFields = null;
             while (true) {
               uint tag = input.ReadTag();
               switch (tag) {
                 case 0: {
-                  this.UnknownFields = unknownFields.Build();
+                  if (unknownFields != null) {
+                    this.UnknownFields = unknownFields.Build();
+                  }
                   return this;
                 }
                 default: {
-                  if (!ParseUnknownField(input, unknownFields, extensionRegistry, tag)) {
-                    this.UnknownFields = unknownFields.Build();
+                  if (pb::WireFormat.IsEndGroupTag(tag)) {
+                    if (unknownFields != null) {
+                      this.UnknownFields = unknownFields.Build();
+                    }
                     return this;
                   }
+                  if (unknownFields == null) {
+                    unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+                  }
+                  ParseUnknownField(input, unknownFields, extensionRegistry, tag);
                   break;
                 }
                 case 136: {
@@ -1288,19 +1304,27 @@
           }
           
           public override Builder MergeFrom(pb::CodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
-            pb::UnknownFieldSet.Builder unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+            pb::UnknownFieldSet.Builder unknownFields = null;
             while (true) {
               uint tag = input.ReadTag();
               switch (tag) {
                 case 0: {
-                  this.UnknownFields = unknownFields.Build();
+                  if (unknownFields != null) {
+                    this.UnknownFields = unknownFields.Build();
+                  }
                   return this;
                 }
                 default: {
-                  if (!ParseUnknownField(input, unknownFields, extensionRegistry, tag)) {
-                    this.UnknownFields = unknownFields.Build();
+                  if (pb::WireFormat.IsEndGroupTag(tag)) {
+                    if (unknownFields != null) {
+                      this.UnknownFields = unknownFields.Build();
+                    }
                     return this;
                   }
+                  if (unknownFields == null) {
+                    unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+                  }
+                  ParseUnknownField(input, unknownFields, extensionRegistry, tag);
                   break;
                 }
                 case 376: {
@@ -2872,19 +2896,27 @@
       }
       
       public override Builder MergeFrom(pb::CodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
-        pb::UnknownFieldSet.Builder unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+        pb::UnknownFieldSet.Builder unknownFields = null;
         while (true) {
           uint tag = input.ReadTag();
           switch (tag) {
             case 0: {
-              this.UnknownFields = unknownFields.Build();
+              if (unknownFields != null) {
+                this.UnknownFields = unknownFields.Build();
+              }
               return this;
             }
             default: {
-              if (!ParseUnknownField(input, unknownFields, extensionRegistry, tag)) {
-                this.UnknownFields = unknownFields.Build();
+              if (pb::WireFormat.IsEndGroupTag(tag)) {
+                if (unknownFields != null) {
+                  this.UnknownFields = unknownFields.Build();
+                }
                 return this;
               }
+              if (unknownFields == null) {
+                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+              }
+              ParseUnknownField(input, unknownFields, extensionRegistry, tag);
               break;
             }
             case 8: {
@@ -2986,6 +3018,9 @@
             case 168: {
               int rawValue = input.ReadEnum();
               if (!global::System.Enum.IsDefined(typeof(global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedEnum), rawValue)) {
+                if (unknownFields == null) {
+                  unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+                }
                 unknownFields.MergeVarintField(21, (ulong) rawValue);
               } else {
                 OptionalNestedEnum = (global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedEnum) rawValue;
@@ -2995,6 +3030,9 @@
             case 176: {
               int rawValue = input.ReadEnum();
               if (!global::System.Enum.IsDefined(typeof(global::Google.ProtocolBuffers.TestProtos.ForeignEnum), rawValue)) {
+                if (unknownFields == null) {
+                  unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+                }
                 unknownFields.MergeVarintField(22, (ulong) rawValue);
               } else {
                 OptionalForeignEnum = (global::Google.ProtocolBuffers.TestProtos.ForeignEnum) rawValue;
@@ -3004,6 +3042,9 @@
             case 184: {
               int rawValue = input.ReadEnum();
               if (!global::System.Enum.IsDefined(typeof(global::Google.ProtocolBuffers.TestProtos.ImportEnum), rawValue)) {
+                if (unknownFields == null) {
+                  unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+                }
                 unknownFields.MergeVarintField(23, (ulong) rawValue);
               } else {
                 OptionalImportEnum = (global::Google.ProtocolBuffers.TestProtos.ImportEnum) rawValue;
@@ -3105,6 +3146,9 @@
             case 408: {
               int rawValue = input.ReadEnum();
               if (!global::System.Enum.IsDefined(typeof(global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedEnum), rawValue)) {
+                if (unknownFields == null) {
+                  unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+                }
                 unknownFields.MergeVarintField(51, (ulong) rawValue);
               } else {
                 AddRepeatedNestedEnum((global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedEnum) rawValue);
@@ -3114,6 +3158,9 @@
             case 416: {
               int rawValue = input.ReadEnum();
               if (!global::System.Enum.IsDefined(typeof(global::Google.ProtocolBuffers.TestProtos.ForeignEnum), rawValue)) {
+                if (unknownFields == null) {
+                  unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+                }
                 unknownFields.MergeVarintField(52, (ulong) rawValue);
               } else {
                 AddRepeatedForeignEnum((global::Google.ProtocolBuffers.TestProtos.ForeignEnum) rawValue);
@@ -3123,6 +3170,9 @@
             case 424: {
               int rawValue = input.ReadEnum();
               if (!global::System.Enum.IsDefined(typeof(global::Google.ProtocolBuffers.TestProtos.ImportEnum), rawValue)) {
+                if (unknownFields == null) {
+                  unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+                }
                 unknownFields.MergeVarintField(53, (ulong) rawValue);
               } else {
                 AddRepeatedImportEnum((global::Google.ProtocolBuffers.TestProtos.ImportEnum) rawValue);
@@ -3200,6 +3250,9 @@
             case 648: {
               int rawValue = input.ReadEnum();
               if (!global::System.Enum.IsDefined(typeof(global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedEnum), rawValue)) {
+                if (unknownFields == null) {
+                  unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+                }
                 unknownFields.MergeVarintField(81, (ulong) rawValue);
               } else {
                 DefaultNestedEnum = (global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedEnum) rawValue;
@@ -3209,6 +3262,9 @@
             case 656: {
               int rawValue = input.ReadEnum();
               if (!global::System.Enum.IsDefined(typeof(global::Google.ProtocolBuffers.TestProtos.ForeignEnum), rawValue)) {
+                if (unknownFields == null) {
+                  unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+                }
                 unknownFields.MergeVarintField(82, (ulong) rawValue);
               } else {
                 DefaultForeignEnum = (global::Google.ProtocolBuffers.TestProtos.ForeignEnum) rawValue;
@@ -3218,6 +3274,9 @@
             case 664: {
               int rawValue = input.ReadEnum();
               if (!global::System.Enum.IsDefined(typeof(global::Google.ProtocolBuffers.TestProtos.ImportEnum), rawValue)) {
+                if (unknownFields == null) {
+                  unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+                }
                 unknownFields.MergeVarintField(83, (ulong) rawValue);
               } else {
                 DefaultImportEnum = (global::Google.ProtocolBuffers.TestProtos.ImportEnum) rawValue;
@@ -4940,19 +4999,27 @@
       }
       
       public override Builder MergeFrom(pb::CodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
-        pb::UnknownFieldSet.Builder unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+        pb::UnknownFieldSet.Builder unknownFields = null;
         while (true) {
           uint tag = input.ReadTag();
           switch (tag) {
             case 0: {
-              this.UnknownFields = unknownFields.Build();
+              if (unknownFields != null) {
+                this.UnknownFields = unknownFields.Build();
+              }
               return this;
             }
             default: {
-              if (!ParseUnknownField(input, unknownFields, extensionRegistry, tag)) {
-                this.UnknownFields = unknownFields.Build();
+              if (pb::WireFormat.IsEndGroupTag(tag)) {
+                if (unknownFields != null) {
+                  this.UnknownFields = unknownFields.Build();
+                }
                 return this;
               }
+              if (unknownFields == null) {
+                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+              }
+              ParseUnknownField(input, unknownFields, extensionRegistry, tag);
               break;
             }
             case 8: {
@@ -5120,19 +5187,27 @@
       }
       
       public override Builder MergeFrom(pb::CodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
-        pb::UnknownFieldSet.Builder unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+        pb::UnknownFieldSet.Builder unknownFields = null;
         while (true) {
           uint tag = input.ReadTag();
           switch (tag) {
             case 0: {
-              this.UnknownFields = unknownFields.Build();
+              if (unknownFields != null) {
+                this.UnknownFields = unknownFields.Build();
+              }
               return this;
             }
             default: {
-              if (!ParseUnknownField(input, unknownFields, extensionRegistry, tag)) {
-                this.UnknownFields = unknownFields.Build();
+              if (pb::WireFormat.IsEndGroupTag(tag)) {
+                if (unknownFields != null) {
+                  this.UnknownFields = unknownFields.Build();
+                }
                 return this;
               }
+              if (unknownFields == null) {
+                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+              }
+              ParseUnknownField(input, unknownFields, extensionRegistry, tag);
               break;
             }
           }
@@ -5291,19 +5366,27 @@
       }
       
       public override Builder MergeFrom(pb::CodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
-        pb::UnknownFieldSet.Builder unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+        pb::UnknownFieldSet.Builder unknownFields = null;
         while (true) {
           uint tag = input.ReadTag();
           switch (tag) {
             case 0: {
-              this.UnknownFields = unknownFields.Build();
+              if (unknownFields != null) {
+                this.UnknownFields = unknownFields.Build();
+              }
               return this;
             }
             default: {
-              if (!ParseUnknownField(input, unknownFields, extensionRegistry, tag)) {
-                this.UnknownFields = unknownFields.Build();
+              if (pb::WireFormat.IsEndGroupTag(tag)) {
+                if (unknownFields != null) {
+                  this.UnknownFields = unknownFields.Build();
+                }
                 return this;
               }
+              if (unknownFields == null) {
+                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+              }
+              ParseUnknownField(input, unknownFields, extensionRegistry, tag);
               break;
             }
             case 136: {
@@ -5484,19 +5567,27 @@
       }
       
       public override Builder MergeFrom(pb::CodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
-        pb::UnknownFieldSet.Builder unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+        pb::UnknownFieldSet.Builder unknownFields = null;
         while (true) {
           uint tag = input.ReadTag();
           switch (tag) {
             case 0: {
-              this.UnknownFields = unknownFields.Build();
+              if (unknownFields != null) {
+                this.UnknownFields = unknownFields.Build();
+              }
               return this;
             }
             default: {
-              if (!ParseUnknownField(input, unknownFields, extensionRegistry, tag)) {
-                this.UnknownFields = unknownFields.Build();
+              if (pb::WireFormat.IsEndGroupTag(tag)) {
+                if (unknownFields != null) {
+                  this.UnknownFields = unknownFields.Build();
+                }
                 return this;
               }
+              if (unknownFields == null) {
+                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+              }
+              ParseUnknownField(input, unknownFields, extensionRegistry, tag);
               break;
             }
             case 376: {
@@ -6261,19 +6352,27 @@
       }
       
       public override Builder MergeFrom(pb::CodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
-        pb::UnknownFieldSet.Builder unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+        pb::UnknownFieldSet.Builder unknownFields = null;
         while (true) {
           uint tag = input.ReadTag();
           switch (tag) {
             case 0: {
-              this.UnknownFields = unknownFields.Build();
+              if (unknownFields != null) {
+                this.UnknownFields = unknownFields.Build();
+              }
               return this;
             }
             default: {
-              if (!ParseUnknownField(input, unknownFields, extensionRegistry, tag)) {
-                this.UnknownFields = unknownFields.Build();
+              if (pb::WireFormat.IsEndGroupTag(tag)) {
+                if (unknownFields != null) {
+                  this.UnknownFields = unknownFields.Build();
+                }
                 return this;
               }
+              if (unknownFields == null) {
+                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+              }
+              ParseUnknownField(input, unknownFields, extensionRegistry, tag);
               break;
             }
             case 8: {
@@ -7203,19 +7302,27 @@
       }
       
       public override Builder MergeFrom(pb::CodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
-        pb::UnknownFieldSet.Builder unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+        pb::UnknownFieldSet.Builder unknownFields = null;
         while (true) {
           uint tag = input.ReadTag();
           switch (tag) {
             case 0: {
-              this.UnknownFields = unknownFields.Build();
+              if (unknownFields != null) {
+                this.UnknownFields = unknownFields.Build();
+              }
               return this;
             }
             default: {
-              if (!ParseUnknownField(input, unknownFields, extensionRegistry, tag)) {
-                this.UnknownFields = unknownFields.Build();
+              if (pb::WireFormat.IsEndGroupTag(tag)) {
+                if (unknownFields != null) {
+                  this.UnknownFields = unknownFields.Build();
+                }
                 return this;
               }
+              if (unknownFields == null) {
+                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+              }
+              ParseUnknownField(input, unknownFields, extensionRegistry, tag);
               break;
             }
             case 10: {
@@ -7485,19 +7592,27 @@
       }
       
       public override Builder MergeFrom(pb::CodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
-        pb::UnknownFieldSet.Builder unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+        pb::UnknownFieldSet.Builder unknownFields = null;
         while (true) {
           uint tag = input.ReadTag();
           switch (tag) {
             case 0: {
-              this.UnknownFields = unknownFields.Build();
+              if (unknownFields != null) {
+                this.UnknownFields = unknownFields.Build();
+              }
               return this;
             }
             default: {
-              if (!ParseUnknownField(input, unknownFields, extensionRegistry, tag)) {
-                this.UnknownFields = unknownFields.Build();
+              if (pb::WireFormat.IsEndGroupTag(tag)) {
+                if (unknownFields != null) {
+                  this.UnknownFields = unknownFields.Build();
+                }
                 return this;
               }
+              if (unknownFields == null) {
+                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+              }
+              ParseUnknownField(input, unknownFields, extensionRegistry, tag);
               break;
             }
             case 10: {
@@ -7683,19 +7798,27 @@
       }
       
       public override Builder MergeFrom(pb::CodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
-        pb::UnknownFieldSet.Builder unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+        pb::UnknownFieldSet.Builder unknownFields = null;
         while (true) {
           uint tag = input.ReadTag();
           switch (tag) {
             case 0: {
-              this.UnknownFields = unknownFields.Build();
+              if (unknownFields != null) {
+                this.UnknownFields = unknownFields.Build();
+              }
               return this;
             }
             default: {
-              if (!ParseUnknownField(input, unknownFields, extensionRegistry, tag)) {
-                this.UnknownFields = unknownFields.Build();
+              if (pb::WireFormat.IsEndGroupTag(tag)) {
+                if (unknownFields != null) {
+                  this.UnknownFields = unknownFields.Build();
+                }
                 return this;
               }
+              if (unknownFields == null) {
+                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+              }
+              ParseUnknownField(input, unknownFields, extensionRegistry, tag);
               break;
             }
           }
@@ -7841,19 +7964,27 @@
       }
       
       public override Builder MergeFrom(pb::CodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
-        pb::UnknownFieldSet.Builder unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+        pb::UnknownFieldSet.Builder unknownFields = null;
         while (true) {
           uint tag = input.ReadTag();
           switch (tag) {
             case 0: {
-              this.UnknownFields = unknownFields.Build();
+              if (unknownFields != null) {
+                this.UnknownFields = unknownFields.Build();
+              }
               return this;
             }
             default: {
-              if (!ParseUnknownField(input, unknownFields, extensionRegistry, tag)) {
-                this.UnknownFields = unknownFields.Build();
+              if (pb::WireFormat.IsEndGroupTag(tag)) {
+                if (unknownFields != null) {
+                  this.UnknownFields = unknownFields.Build();
+                }
                 return this;
               }
+              if (unknownFields == null) {
+                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+              }
+              ParseUnknownField(input, unknownFields, extensionRegistry, tag);
               break;
             }
           }
@@ -8030,19 +8161,27 @@
       }
       
       public override Builder MergeFrom(pb::CodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
-        pb::UnknownFieldSet.Builder unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+        pb::UnknownFieldSet.Builder unknownFields = null;
         while (true) {
           uint tag = input.ReadTag();
           switch (tag) {
             case 0: {
-              this.UnknownFields = unknownFields.Build();
+              if (unknownFields != null) {
+                this.UnknownFields = unknownFields.Build();
+              }
               return this;
             }
             default: {
-              if (!ParseUnknownField(input, unknownFields, extensionRegistry, tag)) {
-                this.UnknownFields = unknownFields.Build();
+              if (pb::WireFormat.IsEndGroupTag(tag)) {
+                if (unknownFields != null) {
+                  this.UnknownFields = unknownFields.Build();
+                }
                 return this;
               }
+              if (unknownFields == null) {
+                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+              }
+              ParseUnknownField(input, unknownFields, extensionRegistry, tag);
               break;
             }
             case 8: {
@@ -8263,19 +8402,27 @@
       }
       
       public override Builder MergeFrom(pb::CodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
-        pb::UnknownFieldSet.Builder unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+        pb::UnknownFieldSet.Builder unknownFields = null;
         while (true) {
           uint tag = input.ReadTag();
           switch (tag) {
             case 0: {
-              this.UnknownFields = unknownFields.Build();
+              if (unknownFields != null) {
+                this.UnknownFields = unknownFields.Build();
+              }
               return this;
             }
             default: {
-              if (!ParseUnknownField(input, unknownFields, extensionRegistry, tag)) {
-                this.UnknownFields = unknownFields.Build();
+              if (pb::WireFormat.IsEndGroupTag(tag)) {
+                if (unknownFields != null) {
+                  this.UnknownFields = unknownFields.Build();
+                }
                 return this;
               }
+              if (unknownFields == null) {
+                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+              }
+              ParseUnknownField(input, unknownFields, extensionRegistry, tag);
               break;
             }
             case 10: {
@@ -8501,19 +8648,27 @@
       }
       
       public override Builder MergeFrom(pb::CodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
-        pb::UnknownFieldSet.Builder unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+        pb::UnknownFieldSet.Builder unknownFields = null;
         while (true) {
           uint tag = input.ReadTag();
           switch (tag) {
             case 0: {
-              this.UnknownFields = unknownFields.Build();
+              if (unknownFields != null) {
+                this.UnknownFields = unknownFields.Build();
+              }
               return this;
             }
             default: {
-              if (!ParseUnknownField(input, unknownFields, extensionRegistry, tag)) {
-                this.UnknownFields = unknownFields.Build();
+              if (pb::WireFormat.IsEndGroupTag(tag)) {
+                if (unknownFields != null) {
+                  this.UnknownFields = unknownFields.Build();
+                }
                 return this;
               }
+              if (unknownFields == null) {
+                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+              }
+              ParseUnknownField(input, unknownFields, extensionRegistry, tag);
               break;
             }
             case 10: {
@@ -8735,19 +8890,27 @@
       }
       
       public override Builder MergeFrom(pb::CodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
-        pb::UnknownFieldSet.Builder unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+        pb::UnknownFieldSet.Builder unknownFields = null;
         while (true) {
           uint tag = input.ReadTag();
           switch (tag) {
             case 0: {
-              this.UnknownFields = unknownFields.Build();
+              if (unknownFields != null) {
+                this.UnknownFields = unknownFields.Build();
+              }
               return this;
             }
             default: {
-              if (!ParseUnknownField(input, unknownFields, extensionRegistry, tag)) {
-                this.UnknownFields = unknownFields.Build();
+              if (pb::WireFormat.IsEndGroupTag(tag)) {
+                if (unknownFields != null) {
+                  this.UnknownFields = unknownFields.Build();
+                }
                 return this;
               }
+              if (unknownFields == null) {
+                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+              }
+              ParseUnknownField(input, unknownFields, extensionRegistry, tag);
               break;
             }
             case 10: {
@@ -8997,19 +9160,27 @@
           }
           
           public override Builder MergeFrom(pb::CodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
-            pb::UnknownFieldSet.Builder unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+            pb::UnknownFieldSet.Builder unknownFields = null;
             while (true) {
               uint tag = input.ReadTag();
               switch (tag) {
                 case 0: {
-                  this.UnknownFields = unknownFields.Build();
+                  if (unknownFields != null) {
+                    this.UnknownFields = unknownFields.Build();
+                  }
                   return this;
                 }
                 default: {
-                  if (!ParseUnknownField(input, unknownFields, extensionRegistry, tag)) {
-                    this.UnknownFields = unknownFields.Build();
+                  if (pb::WireFormat.IsEndGroupTag(tag)) {
+                    if (unknownFields != null) {
+                      this.UnknownFields = unknownFields.Build();
+                    }
                     return this;
                   }
+                  if (unknownFields == null) {
+                    unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+                  }
+                  ParseUnknownField(input, unknownFields, extensionRegistry, tag);
                   break;
                 }
                 case 8: {
@@ -9190,19 +9361,27 @@
           }
           
           public override Builder MergeFrom(pb::CodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
-            pb::UnknownFieldSet.Builder unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+            pb::UnknownFieldSet.Builder unknownFields = null;
             while (true) {
               uint tag = input.ReadTag();
               switch (tag) {
                 case 0: {
-                  this.UnknownFields = unknownFields.Build();
+                  if (unknownFields != null) {
+                    this.UnknownFields = unknownFields.Build();
+                  }
                   return this;
                 }
                 default: {
-                  if (!ParseUnknownField(input, unknownFields, extensionRegistry, tag)) {
-                    this.UnknownFields = unknownFields.Build();
+                  if (pb::WireFormat.IsEndGroupTag(tag)) {
+                    if (unknownFields != null) {
+                      this.UnknownFields = unknownFields.Build();
+                    }
                     return this;
                   }
+                  if (unknownFields == null) {
+                    unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+                  }
+                  ParseUnknownField(input, unknownFields, extensionRegistry, tag);
                   break;
                 }
                 case 8: {
@@ -9400,19 +9579,27 @@
       }
       
       public override Builder MergeFrom(pb::CodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
-        pb::UnknownFieldSet.Builder unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+        pb::UnknownFieldSet.Builder unknownFields = null;
         while (true) {
           uint tag = input.ReadTag();
           switch (tag) {
             case 0: {
-              this.UnknownFields = unknownFields.Build();
+              if (unknownFields != null) {
+                this.UnknownFields = unknownFields.Build();
+              }
               return this;
             }
             default: {
-              if (!ParseUnknownField(input, unknownFields, extensionRegistry, tag)) {
-                this.UnknownFields = unknownFields.Build();
+              if (pb::WireFormat.IsEndGroupTag(tag)) {
+                if (unknownFields != null) {
+                  this.UnknownFields = unknownFields.Build();
+                }
                 return this;
               }
+              if (unknownFields == null) {
+                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+              }
+              ParseUnknownField(input, unknownFields, extensionRegistry, tag);
               break;
             }
             case 8: {
@@ -9738,19 +9925,27 @@
           }
           
           public override Builder MergeFrom(pb::CodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
-            pb::UnknownFieldSet.Builder unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+            pb::UnknownFieldSet.Builder unknownFields = null;
             while (true) {
               uint tag = input.ReadTag();
               switch (tag) {
                 case 0: {
-                  this.UnknownFields = unknownFields.Build();
+                  if (unknownFields != null) {
+                    this.UnknownFields = unknownFields.Build();
+                  }
                   return this;
                 }
                 default: {
-                  if (!ParseUnknownField(input, unknownFields, extensionRegistry, tag)) {
-                    this.UnknownFields = unknownFields.Build();
+                  if (pb::WireFormat.IsEndGroupTag(tag)) {
+                    if (unknownFields != null) {
+                      this.UnknownFields = unknownFields.Build();
+                    }
                     return this;
                   }
+                  if (unknownFields == null) {
+                    unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+                  }
+                  ParseUnknownField(input, unknownFields, extensionRegistry, tag);
                   break;
                 }
                 case 8: {
@@ -9964,19 +10159,27 @@
       }
       
       public override Builder MergeFrom(pb::CodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
-        pb::UnknownFieldSet.Builder unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+        pb::UnknownFieldSet.Builder unknownFields = null;
         while (true) {
           uint tag = input.ReadTag();
           switch (tag) {
             case 0: {
-              this.UnknownFields = unknownFields.Build();
+              if (unknownFields != null) {
+                this.UnknownFields = unknownFields.Build();
+              }
               return this;
             }
             default: {
-              if (!ParseUnknownField(input, unknownFields, extensionRegistry, tag)) {
-                this.UnknownFields = unknownFields.Build();
+              if (pb::WireFormat.IsEndGroupTag(tag)) {
+                if (unknownFields != null) {
+                  this.UnknownFields = unknownFields.Build();
+                }
                 return this;
               }
+              if (unknownFields == null) {
+                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+              }
+              ParseUnknownField(input, unknownFields, extensionRegistry, tag);
               break;
             }
             case 10: {
@@ -10433,19 +10636,27 @@
       }
       
       public override Builder MergeFrom(pb::CodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
-        pb::UnknownFieldSet.Builder unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+        pb::UnknownFieldSet.Builder unknownFields = null;
         while (true) {
           uint tag = input.ReadTag();
           switch (tag) {
             case 0: {
-              this.UnknownFields = unknownFields.Build();
+              if (unknownFields != null) {
+                this.UnknownFields = unknownFields.Build();
+              }
               return this;
             }
             default: {
-              if (!ParseUnknownField(input, unknownFields, extensionRegistry, tag)) {
-                this.UnknownFields = unknownFields.Build();
+              if (pb::WireFormat.IsEndGroupTag(tag)) {
+                if (unknownFields != null) {
+                  this.UnknownFields = unknownFields.Build();
+                }
                 return this;
               }
+              if (unknownFields == null) {
+                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+              }
+              ParseUnknownField(input, unknownFields, extensionRegistry, tag);
               break;
             }
             case 8: {
@@ -10459,6 +10670,9 @@
             case 24: {
               int rawValue = input.ReadEnum();
               if (!global::System.Enum.IsDefined(typeof(global::Google.ProtocolBuffers.TestProtos.ForeignEnum), rawValue)) {
+                if (unknownFields == null) {
+                  unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+                }
                 unknownFields.MergeVarintField(3, (ulong) rawValue);
               } else {
                 EnumField = (global::Google.ProtocolBuffers.TestProtos.ForeignEnum) rawValue;
@@ -10493,6 +10707,9 @@
             case 72: {
               int rawValue = input.ReadEnum();
               if (!global::System.Enum.IsDefined(typeof(global::Google.ProtocolBuffers.TestProtos.ForeignEnum), rawValue)) {
+                if (unknownFields == null) {
+                  unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+                }
                 unknownFields.MergeVarintField(9, (ulong) rawValue);
               } else {
                 AddRepeatedEnumField((global::Google.ProtocolBuffers.TestProtos.ForeignEnum) rawValue);
@@ -11014,19 +11231,27 @@
       }
       
       public override Builder MergeFrom(pb::CodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
-        pb::UnknownFieldSet.Builder unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+        pb::UnknownFieldSet.Builder unknownFields = null;
         while (true) {
           uint tag = input.ReadTag();
           switch (tag) {
             case 0: {
-              this.UnknownFields = unknownFields.Build();
+              if (unknownFields != null) {
+                this.UnknownFields = unknownFields.Build();
+              }
               return this;
             }
             default: {
-              if (!ParseUnknownField(input, unknownFields, extensionRegistry, tag)) {
-                this.UnknownFields = unknownFields.Build();
+              if (pb::WireFormat.IsEndGroupTag(tag)) {
+                if (unknownFields != null) {
+                  this.UnknownFields = unknownFields.Build();
+                }
                 return this;
               }
+              if (unknownFields == null) {
+                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+              }
+              ParseUnknownField(input, unknownFields, extensionRegistry, tag);
               break;
             }
             case 8: {
@@ -11342,19 +11567,27 @@
       }
       
       public override Builder MergeFrom(pb::CodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
-        pb::UnknownFieldSet.Builder unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+        pb::UnknownFieldSet.Builder unknownFields = null;
         while (true) {
           uint tag = input.ReadTag();
           switch (tag) {
             case 0: {
-              this.UnknownFields = unknownFields.Build();
+              if (unknownFields != null) {
+                this.UnknownFields = unknownFields.Build();
+              }
               return this;
             }
             default: {
-              if (!ParseUnknownField(input, unknownFields, extensionRegistry, tag)) {
-                this.UnknownFields = unknownFields.Build();
+              if (pb::WireFormat.IsEndGroupTag(tag)) {
+                if (unknownFields != null) {
+                  this.UnknownFields = unknownFields.Build();
+                }
                 return this;
               }
+              if (unknownFields == null) {
+                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+              }
+              ParseUnknownField(input, unknownFields, extensionRegistry, tag);
               break;
             }
             case 10: {
@@ -12079,19 +12312,27 @@
       }
       
       public override Builder MergeFrom(pb::CodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
-        pb::UnknownFieldSet.Builder unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+        pb::UnknownFieldSet.Builder unknownFields = null;
         while (true) {
           uint tag = input.ReadTag();
           switch (tag) {
             case 0: {
-              this.UnknownFields = unknownFields.Build();
+              if (unknownFields != null) {
+                this.UnknownFields = unknownFields.Build();
+              }
               return this;
             }
             default: {
-              if (!ParseUnknownField(input, unknownFields, extensionRegistry, tag)) {
-                this.UnknownFields = unknownFields.Build();
+              if (pb::WireFormat.IsEndGroupTag(tag)) {
+                if (unknownFields != null) {
+                  this.UnknownFields = unknownFields.Build();
+                }
                 return this;
               }
+              if (unknownFields == null) {
+                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+              }
+              ParseUnknownField(input, unknownFields, extensionRegistry, tag);
               break;
             }
             case 722: {
@@ -12217,6 +12458,9 @@
               while (!input.ReachedLimit) {
                 int rawValue = input.ReadEnum();
                 if (!global::System.Enum.IsDefined(typeof(global::Google.ProtocolBuffers.TestProtos.ForeignEnum), rawValue)) {
+                  if (unknownFields == null) {
+                    unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+                  }
                   unknownFields.MergeVarintField(103, (ulong) rawValue);
                 } else {
                   AddPackedEnum((global::Google.ProtocolBuffers.TestProtos.ForeignEnum) rawValue);
@@ -12732,19 +12976,27 @@
       }
       
       public override Builder MergeFrom(pb::CodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
-        pb::UnknownFieldSet.Builder unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+        pb::UnknownFieldSet.Builder unknownFields = null;
         while (true) {
           uint tag = input.ReadTag();
           switch (tag) {
             case 0: {
-              this.UnknownFields = unknownFields.Build();
+              if (unknownFields != null) {
+                this.UnknownFields = unknownFields.Build();
+              }
               return this;
             }
             default: {
-              if (!ParseUnknownField(input, unknownFields, extensionRegistry, tag)) {
-                this.UnknownFields = unknownFields.Build();
+              if (pb::WireFormat.IsEndGroupTag(tag)) {
+                if (unknownFields != null) {
+                  this.UnknownFields = unknownFields.Build();
+                }
                 return this;
               }
+              if (unknownFields == null) {
+                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+              }
+              ParseUnknownField(input, unknownFields, extensionRegistry, tag);
               break;
             }
           }
@@ -12885,19 +13137,27 @@
       }
       
       public override Builder MergeFrom(pb::CodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
-        pb::UnknownFieldSet.Builder unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+        pb::UnknownFieldSet.Builder unknownFields = null;
         while (true) {
           uint tag = input.ReadTag();
           switch (tag) {
             case 0: {
-              this.UnknownFields = unknownFields.Build();
+              if (unknownFields != null) {
+                this.UnknownFields = unknownFields.Build();
+              }
               return this;
             }
             default: {
-              if (!ParseUnknownField(input, unknownFields, extensionRegistry, tag)) {
-                this.UnknownFields = unknownFields.Build();
+              if (pb::WireFormat.IsEndGroupTag(tag)) {
+                if (unknownFields != null) {
+                  this.UnknownFields = unknownFields.Build();
+                }
                 return this;
               }
+              if (unknownFields == null) {
+                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+              }
+              ParseUnknownField(input, unknownFields, extensionRegistry, tag);
               break;
             }
           }
@@ -13038,19 +13298,27 @@
       }
       
       public override Builder MergeFrom(pb::CodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
-        pb::UnknownFieldSet.Builder unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+        pb::UnknownFieldSet.Builder unknownFields = null;
         while (true) {
           uint tag = input.ReadTag();
           switch (tag) {
             case 0: {
-              this.UnknownFields = unknownFields.Build();
+              if (unknownFields != null) {
+                this.UnknownFields = unknownFields.Build();
+              }
               return this;
             }
             default: {
-              if (!ParseUnknownField(input, unknownFields, extensionRegistry, tag)) {
-                this.UnknownFields = unknownFields.Build();
+              if (pb::WireFormat.IsEndGroupTag(tag)) {
+                if (unknownFields != null) {
+                  this.UnknownFields = unknownFields.Build();
+                }
                 return this;
               }
+              if (unknownFields == null) {
+                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+              }
+              ParseUnknownField(input, unknownFields, extensionRegistry, tag);
               break;
             }
           }
@@ -13191,19 +13459,27 @@
       }
       
       public override Builder MergeFrom(pb::CodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
-        pb::UnknownFieldSet.Builder unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+        pb::UnknownFieldSet.Builder unknownFields = null;
         while (true) {
           uint tag = input.ReadTag();
           switch (tag) {
             case 0: {
-              this.UnknownFields = unknownFields.Build();
+              if (unknownFields != null) {
+                this.UnknownFields = unknownFields.Build();
+              }
               return this;
             }
             default: {
-              if (!ParseUnknownField(input, unknownFields, extensionRegistry, tag)) {
-                this.UnknownFields = unknownFields.Build();
+              if (pb::WireFormat.IsEndGroupTag(tag)) {
+                if (unknownFields != null) {
+                  this.UnknownFields = unknownFields.Build();
+                }
                 return this;
               }
+              if (unknownFields == null) {
+                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+              }
+              ParseUnknownField(input, unknownFields, extensionRegistry, tag);
               break;
             }
           }
@@ -13344,19 +13620,27 @@
       }
       
       public override Builder MergeFrom(pb::CodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
-        pb::UnknownFieldSet.Builder unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+        pb::UnknownFieldSet.Builder unknownFields = null;
         while (true) {
           uint tag = input.ReadTag();
           switch (tag) {
             case 0: {
-              this.UnknownFields = unknownFields.Build();
+              if (unknownFields != null) {
+                this.UnknownFields = unknownFields.Build();
+              }
               return this;
             }
             default: {
-              if (!ParseUnknownField(input, unknownFields, extensionRegistry, tag)) {
-                this.UnknownFields = unknownFields.Build();
+              if (pb::WireFormat.IsEndGroupTag(tag)) {
+                if (unknownFields != null) {
+                  this.UnknownFields = unknownFields.Build();
+                }
                 return this;
               }
+              if (unknownFields == null) {
+                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+              }
+              ParseUnknownField(input, unknownFields, extensionRegistry, tag);
               break;
             }
           }
diff --git a/src/ProtocolBuffers/DescriptorProtos/DescriptorProtoFile.cs b/src/ProtocolBuffers/DescriptorProtos/DescriptorProtoFile.cs
index 927d4ae..b02c5ce 100644
--- a/src/ProtocolBuffers/DescriptorProtos/DescriptorProtoFile.cs
+++ b/src/ProtocolBuffers/DescriptorProtos/DescriptorProtoFile.cs
@@ -344,19 +344,27 @@
       }
       
       public override Builder MergeFrom(pb::CodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
-        pb::UnknownFieldSet.Builder unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+        pb::UnknownFieldSet.Builder unknownFields = null;
         while (true) {
           uint tag = input.ReadTag();
           switch (tag) {
             case 0: {
-              this.UnknownFields = unknownFields.Build();
+              if (unknownFields != null) {
+                this.UnknownFields = unknownFields.Build();
+              }
               return this;
             }
             default: {
-              if (!ParseUnknownField(input, unknownFields, extensionRegistry, tag)) {
-                this.UnknownFields = unknownFields.Build();
+              if (pb::WireFormat.IsEndGroupTag(tag)) {
+                if (unknownFields != null) {
+                  this.UnknownFields = unknownFields.Build();
+                }
                 return this;
               }
+              if (unknownFields == null) {
+                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+              }
+              ParseUnknownField(input, unknownFields, extensionRegistry, tag);
               break;
             }
             case 10: {
@@ -722,19 +730,27 @@
       }
       
       public override Builder MergeFrom(pb::CodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
-        pb::UnknownFieldSet.Builder unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+        pb::UnknownFieldSet.Builder unknownFields = null;
         while (true) {
           uint tag = input.ReadTag();
           switch (tag) {
             case 0: {
-              this.UnknownFields = unknownFields.Build();
+              if (unknownFields != null) {
+                this.UnknownFields = unknownFields.Build();
+              }
               return this;
             }
             default: {
-              if (!ParseUnknownField(input, unknownFields, extensionRegistry, tag)) {
-                this.UnknownFields = unknownFields.Build();
+              if (pb::WireFormat.IsEndGroupTag(tag)) {
+                if (unknownFields != null) {
+                  this.UnknownFields = unknownFields.Build();
+                }
                 return this;
               }
+              if (unknownFields == null) {
+                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+              }
+              ParseUnknownField(input, unknownFields, extensionRegistry, tag);
               break;
             }
             case 10: {
@@ -1234,19 +1250,27 @@
           }
           
           public override Builder MergeFrom(pb::CodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
-            pb::UnknownFieldSet.Builder unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+            pb::UnknownFieldSet.Builder unknownFields = null;
             while (true) {
               uint tag = input.ReadTag();
               switch (tag) {
                 case 0: {
-                  this.UnknownFields = unknownFields.Build();
+                  if (unknownFields != null) {
+                    this.UnknownFields = unknownFields.Build();
+                  }
                   return this;
                 }
                 default: {
-                  if (!ParseUnknownField(input, unknownFields, extensionRegistry, tag)) {
-                    this.UnknownFields = unknownFields.Build();
+                  if (pb::WireFormat.IsEndGroupTag(tag)) {
+                    if (unknownFields != null) {
+                      this.UnknownFields = unknownFields.Build();
+                    }
                     return this;
                   }
+                  if (unknownFields == null) {
+                    unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+                  }
+                  ParseUnknownField(input, unknownFields, extensionRegistry, tag);
                   break;
                 }
                 case 8: {
@@ -1568,19 +1592,27 @@
       }
       
       public override Builder MergeFrom(pb::CodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
-        pb::UnknownFieldSet.Builder unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+        pb::UnknownFieldSet.Builder unknownFields = null;
         while (true) {
           uint tag = input.ReadTag();
           switch (tag) {
             case 0: {
-              this.UnknownFields = unknownFields.Build();
+              if (unknownFields != null) {
+                this.UnknownFields = unknownFields.Build();
+              }
               return this;
             }
             default: {
-              if (!ParseUnknownField(input, unknownFields, extensionRegistry, tag)) {
-                this.UnknownFields = unknownFields.Build();
+              if (pb::WireFormat.IsEndGroupTag(tag)) {
+                if (unknownFields != null) {
+                  this.UnknownFields = unknownFields.Build();
+                }
                 return this;
               }
+              if (unknownFields == null) {
+                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+              }
+              ParseUnknownField(input, unknownFields, extensionRegistry, tag);
               break;
             }
             case 10: {
@@ -2188,19 +2220,27 @@
       }
       
       public override Builder MergeFrom(pb::CodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
-        pb::UnknownFieldSet.Builder unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+        pb::UnknownFieldSet.Builder unknownFields = null;
         while (true) {
           uint tag = input.ReadTag();
           switch (tag) {
             case 0: {
-              this.UnknownFields = unknownFields.Build();
+              if (unknownFields != null) {
+                this.UnknownFields = unknownFields.Build();
+              }
               return this;
             }
             default: {
-              if (!ParseUnknownField(input, unknownFields, extensionRegistry, tag)) {
-                this.UnknownFields = unknownFields.Build();
+              if (pb::WireFormat.IsEndGroupTag(tag)) {
+                if (unknownFields != null) {
+                  this.UnknownFields = unknownFields.Build();
+                }
                 return this;
               }
+              if (unknownFields == null) {
+                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+              }
+              ParseUnknownField(input, unknownFields, extensionRegistry, tag);
               break;
             }
             case 10: {
@@ -2218,6 +2258,9 @@
             case 32: {
               int rawValue = input.ReadEnum();
               if (!global::System.Enum.IsDefined(typeof(global::Google.ProtocolBuffers.DescriptorProtos.FieldDescriptorProto.Types.Label), rawValue)) {
+                if (unknownFields == null) {
+                  unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+                }
                 unknownFields.MergeVarintField(4, (ulong) rawValue);
               } else {
                 Label = (global::Google.ProtocolBuffers.DescriptorProtos.FieldDescriptorProto.Types.Label) rawValue;
@@ -2227,6 +2270,9 @@
             case 40: {
               int rawValue = input.ReadEnum();
               if (!global::System.Enum.IsDefined(typeof(global::Google.ProtocolBuffers.DescriptorProtos.FieldDescriptorProto.Types.Type), rawValue)) {
+                if (unknownFields == null) {
+                  unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+                }
                 unknownFields.MergeVarintField(5, (ulong) rawValue);
               } else {
                 Type = (global::Google.ProtocolBuffers.DescriptorProtos.FieldDescriptorProto.Types.Type) rawValue;
@@ -2617,19 +2663,27 @@
       }
       
       public override Builder MergeFrom(pb::CodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
-        pb::UnknownFieldSet.Builder unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+        pb::UnknownFieldSet.Builder unknownFields = null;
         while (true) {
           uint tag = input.ReadTag();
           switch (tag) {
             case 0: {
-              this.UnknownFields = unknownFields.Build();
+              if (unknownFields != null) {
+                this.UnknownFields = unknownFields.Build();
+              }
               return this;
             }
             default: {
-              if (!ParseUnknownField(input, unknownFields, extensionRegistry, tag)) {
-                this.UnknownFields = unknownFields.Build();
+              if (pb::WireFormat.IsEndGroupTag(tag)) {
+                if (unknownFields != null) {
+                  this.UnknownFields = unknownFields.Build();
+                }
                 return this;
               }
+              if (unknownFields == null) {
+                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+              }
+              ParseUnknownField(input, unknownFields, extensionRegistry, tag);
               break;
             }
             case 10: {
@@ -2939,19 +2993,27 @@
       }
       
       public override Builder MergeFrom(pb::CodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
-        pb::UnknownFieldSet.Builder unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+        pb::UnknownFieldSet.Builder unknownFields = null;
         while (true) {
           uint tag = input.ReadTag();
           switch (tag) {
             case 0: {
-              this.UnknownFields = unknownFields.Build();
+              if (unknownFields != null) {
+                this.UnknownFields = unknownFields.Build();
+              }
               return this;
             }
             default: {
-              if (!ParseUnknownField(input, unknownFields, extensionRegistry, tag)) {
-                this.UnknownFields = unknownFields.Build();
+              if (pb::WireFormat.IsEndGroupTag(tag)) {
+                if (unknownFields != null) {
+                  this.UnknownFields = unknownFields.Build();
+                }
                 return this;
               }
+              if (unknownFields == null) {
+                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+              }
+              ParseUnknownField(input, unknownFields, extensionRegistry, tag);
               break;
             }
             case 10: {
@@ -3245,19 +3307,27 @@
       }
       
       public override Builder MergeFrom(pb::CodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
-        pb::UnknownFieldSet.Builder unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+        pb::UnknownFieldSet.Builder unknownFields = null;
         while (true) {
           uint tag = input.ReadTag();
           switch (tag) {
             case 0: {
-              this.UnknownFields = unknownFields.Build();
+              if (unknownFields != null) {
+                this.UnknownFields = unknownFields.Build();
+              }
               return this;
             }
             default: {
-              if (!ParseUnknownField(input, unknownFields, extensionRegistry, tag)) {
-                this.UnknownFields = unknownFields.Build();
+              if (pb::WireFormat.IsEndGroupTag(tag)) {
+                if (unknownFields != null) {
+                  this.UnknownFields = unknownFields.Build();
+                }
                 return this;
               }
+              if (unknownFields == null) {
+                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+              }
+              ParseUnknownField(input, unknownFields, extensionRegistry, tag);
               break;
             }
             case 10: {
@@ -3585,19 +3655,27 @@
       }
       
       public override Builder MergeFrom(pb::CodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
-        pb::UnknownFieldSet.Builder unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+        pb::UnknownFieldSet.Builder unknownFields = null;
         while (true) {
           uint tag = input.ReadTag();
           switch (tag) {
             case 0: {
-              this.UnknownFields = unknownFields.Build();
+              if (unknownFields != null) {
+                this.UnknownFields = unknownFields.Build();
+              }
               return this;
             }
             default: {
-              if (!ParseUnknownField(input, unknownFields, extensionRegistry, tag)) {
-                this.UnknownFields = unknownFields.Build();
+              if (pb::WireFormat.IsEndGroupTag(tag)) {
+                if (unknownFields != null) {
+                  this.UnknownFields = unknownFields.Build();
+                }
                 return this;
               }
+              if (unknownFields == null) {
+                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+              }
+              ParseUnknownField(input, unknownFields, extensionRegistry, tag);
               break;
             }
             case 10: {
@@ -3963,19 +4041,27 @@
       }
       
       public override Builder MergeFrom(pb::CodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
-        pb::UnknownFieldSet.Builder unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+        pb::UnknownFieldSet.Builder unknownFields = null;
         while (true) {
           uint tag = input.ReadTag();
           switch (tag) {
             case 0: {
-              this.UnknownFields = unknownFields.Build();
+              if (unknownFields != null) {
+                this.UnknownFields = unknownFields.Build();
+              }
               return this;
             }
             default: {
-              if (!ParseUnknownField(input, unknownFields, extensionRegistry, tag)) {
-                this.UnknownFields = unknownFields.Build();
+              if (pb::WireFormat.IsEndGroupTag(tag)) {
+                if (unknownFields != null) {
+                  this.UnknownFields = unknownFields.Build();
+                }
                 return this;
               }
+              if (unknownFields == null) {
+                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+              }
+              ParseUnknownField(input, unknownFields, extensionRegistry, tag);
               break;
             }
             case 10: {
@@ -3989,6 +4075,9 @@
             case 72: {
               int rawValue = input.ReadEnum();
               if (!global::System.Enum.IsDefined(typeof(global::Google.ProtocolBuffers.DescriptorProtos.FileOptions.Types.OptimizeMode), rawValue)) {
+                if (unknownFields == null) {
+                  unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+                }
                 unknownFields.MergeVarintField(9, (ulong) rawValue);
               } else {
                 OptimizeFor = (global::Google.ProtocolBuffers.DescriptorProtos.FileOptions.Types.OptimizeMode) rawValue;
@@ -4302,19 +4391,27 @@
       }
       
       public override Builder MergeFrom(pb::CodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
-        pb::UnknownFieldSet.Builder unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+        pb::UnknownFieldSet.Builder unknownFields = null;
         while (true) {
           uint tag = input.ReadTag();
           switch (tag) {
             case 0: {
-              this.UnknownFields = unknownFields.Build();
+              if (unknownFields != null) {
+                this.UnknownFields = unknownFields.Build();
+              }
               return this;
             }
             default: {
-              if (!ParseUnknownField(input, unknownFields, extensionRegistry, tag)) {
-                this.UnknownFields = unknownFields.Build();
+              if (pb::WireFormat.IsEndGroupTag(tag)) {
+                if (unknownFields != null) {
+                  this.UnknownFields = unknownFields.Build();
+                }
                 return this;
               }
+              if (unknownFields == null) {
+                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+              }
+              ParseUnknownField(input, unknownFields, extensionRegistry, tag);
               break;
             }
             case 8: {
@@ -4614,24 +4711,35 @@
       }
       
       public override Builder MergeFrom(pb::CodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
-        pb::UnknownFieldSet.Builder unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+        pb::UnknownFieldSet.Builder unknownFields = null;
         while (true) {
           uint tag = input.ReadTag();
           switch (tag) {
             case 0: {
-              this.UnknownFields = unknownFields.Build();
+              if (unknownFields != null) {
+                this.UnknownFields = unknownFields.Build();
+              }
               return this;
             }
             default: {
-              if (!ParseUnknownField(input, unknownFields, extensionRegistry, tag)) {
-                this.UnknownFields = unknownFields.Build();
+              if (pb::WireFormat.IsEndGroupTag(tag)) {
+                if (unknownFields != null) {
+                  this.UnknownFields = unknownFields.Build();
+                }
                 return this;
               }
+              if (unknownFields == null) {
+                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+              }
+              ParseUnknownField(input, unknownFields, extensionRegistry, tag);
               break;
             }
             case 8: {
               int rawValue = input.ReadEnum();
               if (!global::System.Enum.IsDefined(typeof(global::Google.ProtocolBuffers.DescriptorProtos.FieldOptions.Types.CType), rawValue)) {
+                if (unknownFields == null) {
+                  unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+                }
                 unknownFields.MergeVarintField(1, (ulong) rawValue);
               } else {
                 Ctype = (global::Google.ProtocolBuffers.DescriptorProtos.FieldOptions.Types.CType) rawValue;
@@ -4912,19 +5020,27 @@
       }
       
       public override Builder MergeFrom(pb::CodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
-        pb::UnknownFieldSet.Builder unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+        pb::UnknownFieldSet.Builder unknownFields = null;
         while (true) {
           uint tag = input.ReadTag();
           switch (tag) {
             case 0: {
-              this.UnknownFields = unknownFields.Build();
+              if (unknownFields != null) {
+                this.UnknownFields = unknownFields.Build();
+              }
               return this;
             }
             default: {
-              if (!ParseUnknownField(input, unknownFields, extensionRegistry, tag)) {
-                this.UnknownFields = unknownFields.Build();
+              if (pb::WireFormat.IsEndGroupTag(tag)) {
+                if (unknownFields != null) {
+                  this.UnknownFields = unknownFields.Build();
+                }
                 return this;
               }
+              if (unknownFields == null) {
+                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+              }
+              ParseUnknownField(input, unknownFields, extensionRegistry, tag);
               break;
             }
             case 7994: {
@@ -5138,19 +5254,27 @@
       }
       
       public override Builder MergeFrom(pb::CodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
-        pb::UnknownFieldSet.Builder unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+        pb::UnknownFieldSet.Builder unknownFields = null;
         while (true) {
           uint tag = input.ReadTag();
           switch (tag) {
             case 0: {
-              this.UnknownFields = unknownFields.Build();
+              if (unknownFields != null) {
+                this.UnknownFields = unknownFields.Build();
+              }
               return this;
             }
             default: {
-              if (!ParseUnknownField(input, unknownFields, extensionRegistry, tag)) {
-                this.UnknownFields = unknownFields.Build();
+              if (pb::WireFormat.IsEndGroupTag(tag)) {
+                if (unknownFields != null) {
+                  this.UnknownFields = unknownFields.Build();
+                }
                 return this;
               }
+              if (unknownFields == null) {
+                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+              }
+              ParseUnknownField(input, unknownFields, extensionRegistry, tag);
               break;
             }
             case 7994: {
@@ -5364,19 +5488,27 @@
       }
       
       public override Builder MergeFrom(pb::CodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
-        pb::UnknownFieldSet.Builder unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+        pb::UnknownFieldSet.Builder unknownFields = null;
         while (true) {
           uint tag = input.ReadTag();
           switch (tag) {
             case 0: {
-              this.UnknownFields = unknownFields.Build();
+              if (unknownFields != null) {
+                this.UnknownFields = unknownFields.Build();
+              }
               return this;
             }
             default: {
-              if (!ParseUnknownField(input, unknownFields, extensionRegistry, tag)) {
-                this.UnknownFields = unknownFields.Build();
+              if (pb::WireFormat.IsEndGroupTag(tag)) {
+                if (unknownFields != null) {
+                  this.UnknownFields = unknownFields.Build();
+                }
                 return this;
               }
+              if (unknownFields == null) {
+                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+              }
+              ParseUnknownField(input, unknownFields, extensionRegistry, tag);
               break;
             }
             case 7994: {
@@ -5590,19 +5722,27 @@
       }
       
       public override Builder MergeFrom(pb::CodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
-        pb::UnknownFieldSet.Builder unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+        pb::UnknownFieldSet.Builder unknownFields = null;
         while (true) {
           uint tag = input.ReadTag();
           switch (tag) {
             case 0: {
-              this.UnknownFields = unknownFields.Build();
+              if (unknownFields != null) {
+                this.UnknownFields = unknownFields.Build();
+              }
               return this;
             }
             default: {
-              if (!ParseUnknownField(input, unknownFields, extensionRegistry, tag)) {
-                this.UnknownFields = unknownFields.Build();
+              if (pb::WireFormat.IsEndGroupTag(tag)) {
+                if (unknownFields != null) {
+                  this.UnknownFields = unknownFields.Build();
+                }
                 return this;
               }
+              if (unknownFields == null) {
+                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+              }
+              ParseUnknownField(input, unknownFields, extensionRegistry, tag);
               break;
             }
             case 7994: {
@@ -5849,19 +5989,27 @@
           }
           
           public override Builder MergeFrom(pb::CodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
-            pb::UnknownFieldSet.Builder unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+            pb::UnknownFieldSet.Builder unknownFields = null;
             while (true) {
               uint tag = input.ReadTag();
               switch (tag) {
                 case 0: {
-                  this.UnknownFields = unknownFields.Build();
+                  if (unknownFields != null) {
+                    this.UnknownFields = unknownFields.Build();
+                  }
                   return this;
                 }
                 default: {
-                  if (!ParseUnknownField(input, unknownFields, extensionRegistry, tag)) {
-                    this.UnknownFields = unknownFields.Build();
+                  if (pb::WireFormat.IsEndGroupTag(tag)) {
+                    if (unknownFields != null) {
+                      this.UnknownFields = unknownFields.Build();
+                    }
                     return this;
                   }
+                  if (unknownFields == null) {
+                    unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+                  }
+                  ParseUnknownField(input, unknownFields, extensionRegistry, tag);
                   break;
                 }
                 case 10: {
@@ -6142,19 +6290,27 @@
       }
       
       public override Builder MergeFrom(pb::CodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
-        pb::UnknownFieldSet.Builder unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+        pb::UnknownFieldSet.Builder unknownFields = null;
         while (true) {
           uint tag = input.ReadTag();
           switch (tag) {
             case 0: {
-              this.UnknownFields = unknownFields.Build();
+              if (unknownFields != null) {
+                this.UnknownFields = unknownFields.Build();
+              }
               return this;
             }
             default: {
-              if (!ParseUnknownField(input, unknownFields, extensionRegistry, tag)) {
-                this.UnknownFields = unknownFields.Build();
+              if (pb::WireFormat.IsEndGroupTag(tag)) {
+                if (unknownFields != null) {
+                  this.UnknownFields = unknownFields.Build();
+                }
                 return this;
               }
+              if (unknownFields == null) {
+                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+              }
+              ParseUnknownField(input, unknownFields, extensionRegistry, tag);
               break;
             }
             case 18: {
diff --git a/src/ProtocolBuffers/GeneratedBuilder.cs b/src/ProtocolBuffers/GeneratedBuilder.cs
index c678d66..c3543be 100644
--- a/src/ProtocolBuffers/GeneratedBuilder.cs
+++ b/src/ProtocolBuffers/GeneratedBuilder.cs
@@ -158,10 +158,12 @@
     }
 
     public override TBuilder MergeUnknownFields(UnknownFieldSet unknownFields) {
-      TMessage result = MessageBeingBuilt;
-      result.SetUnknownFields(UnknownFieldSet.CreateBuilder(result.UnknownFields)
-          .MergeFrom(unknownFields)
-          .Build());
+      if (unknownFields != UnknownFieldSet.DefaultInstance) {
+        TMessage result = MessageBeingBuilt;
+        result.SetUnknownFields(UnknownFieldSet.CreateBuilder(result.UnknownFields)
+            .MergeFrom(unknownFields)
+            .Build());
+      }
       return ThisBuilder;
     }
 
diff --git a/src/ProtocolBuffers/WireFormat.cs b/src/ProtocolBuffers/WireFormat.cs
index 2bd0a5a..8f723d5 100644
--- a/src/ProtocolBuffers/WireFormat.cs
+++ b/src/ProtocolBuffers/WireFormat.cs
@@ -91,6 +91,10 @@
       return (WireType) (tag & TagTypeMask);
     }
 
+    public static bool IsEndGroupTag(uint tag) {
+      return (WireType)(tag & TagTypeMask) == WireType.EndGroup;
+    }
+
     /// <summary>
     /// Given a tag value, determines the field number (the upper 29 bits).
     /// </summary>