First pass at implementation and testing of reusable builders.
diff --git a/src/ProtocolBuffersLite.Test/TestProtos/UnitTestExtrasFullProtoFile.cs b/src/ProtocolBuffersLite.Test/TestProtos/UnitTestExtrasFullProtoFile.cs
index a9ee777..563cea5 100644
--- a/src/ProtocolBuffersLite.Test/TestProtos/UnitTestExtrasFullProtoFile.cs
+++ b/src/ProtocolBuffersLite.Test/TestProtos/UnitTestExtrasFullProtoFile.cs
@@ -241,7 +241,7 @@
         public override Builder ToBuilder() { return CreateBuilder(this); }

         public override Builder CreateBuilderForType() { return new Builder(); }

         public static Builder CreateBuilder(PhoneNumber prototype) {

-          return (Builder) new Builder().MergeFrom(prototype);

+          return new Builder(prototype);

         }

         

         [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]

@@ -251,21 +251,48 @@
           protected override Builder ThisBuilder {

             get { return this; }

           }

-          public Builder() {}

+          public Builder() {

+            result = DefaultInstance ?? new PhoneNumber();

+            builderIsReadOnly = result == DefaultInstance;

+          }

+          internal Builder(PhoneNumber cloneFrom) {

+            result = cloneFrom;

+            builderIsReadOnly = true;

+          }

           

-          PhoneNumber result = new PhoneNumber();

+          bool builderIsReadOnly;

+          PhoneNumber result;

+          

+          private PhoneNumber PrepareBuilder() {

+            if (builderIsReadOnly) {

+              PhoneNumber original = result;

+              result = new PhoneNumber();

+              builderIsReadOnly = false;

+              MergeFrom(original);

+            }

+            return result;

+          }

+          

+          public override bool IsInitialized {

+            get { return result.IsInitialized; }

+          }

           

           protected override PhoneNumber MessageBeingBuilt {

-            get { return result; }

+            get { return PrepareBuilder(); }

           }

           

           public override Builder Clear() {

-            result = new PhoneNumber();

+            result = DefaultInstance ?? new PhoneNumber();

+            builderIsReadOnly = true;

             return this;

           }

           

           public override Builder Clone() {

-            return new Builder().MergeFrom(result);

+            if (builderIsReadOnly) {

+              return new Builder(result);

+            } else {

+              return new Builder().MergeFrom(result);

+            }

           }

           

           public override pbd::MessageDescriptor DescriptorForType {

@@ -277,12 +304,11 @@
           }

           

           public override PhoneNumber BuildPartial() {

-            if (result == null) {

-              throw new global::System.InvalidOperationException("build() has already been called on this Builder");

+            if (builderIsReadOnly) {

+              return result;

             }

-            PhoneNumber returnMe = result;

-            result = null;

-            return returnMe;

+            builderIsReadOnly = true;

+            return result;

           }

           

           

@@ -295,11 +321,13 @@
           }

           public Builder SetNumber(string value) {

             pb::ThrowHelper.ThrowIfNull(value, "value");

+            PrepareBuilder();

             result.hasNumber = true;

             result.number_ = value;

             return this;

           }

           public Builder ClearNumber() {

+            PrepareBuilder();

             result.hasNumber = false;

             result.number_ = "";

             return this;

@@ -313,11 +341,13 @@
             set { SetType(value); }

           }

           public Builder SetType(global::Google.ProtocolBuffers.TestProtos.TestInteropPerson.Types.PhoneType value) {

+            PrepareBuilder();

             result.hasType = true;

             result.type_ = value;

             return this;

           }

           public Builder ClearType() {

+            PrepareBuilder();

             result.hasType = false;

             result.type_ = global::Google.ProtocolBuffers.TestProtos.TestInteropPerson.Types.PhoneType.HOME;

             return this;

@@ -438,7 +468,7 @@
         public override Builder ToBuilder() { return CreateBuilder(this); }

         public override Builder CreateBuilderForType() { return new Builder(); }

         public static Builder CreateBuilder(Addresses prototype) {

-          return (Builder) new Builder().MergeFrom(prototype);

+          return new Builder(prototype);

         }

         

         [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]

@@ -448,21 +478,48 @@
           protected override Builder ThisBuilder {

             get { return this; }

           }

-          public Builder() {}

+          public Builder() {

+            result = DefaultInstance ?? new Addresses();

+            builderIsReadOnly = result == DefaultInstance;

+          }

+          internal Builder(Addresses cloneFrom) {

+            result = cloneFrom;

+            builderIsReadOnly = true;

+          }

           

-          Addresses result = new Addresses();

+          bool builderIsReadOnly;

+          Addresses result;

+          

+          private Addresses PrepareBuilder() {

+            if (builderIsReadOnly) {

+              Addresses original = result;

+              result = new Addresses();

+              builderIsReadOnly = false;

+              MergeFrom(original);

+            }

+            return result;

+          }

+          

+          public override bool IsInitialized {

+            get { return result.IsInitialized; }

+          }

           

           protected override Addresses MessageBeingBuilt {

-            get { return result; }

+            get { return PrepareBuilder(); }

           }

           

           public override Builder Clear() {

-            result = new Addresses();

+            result = DefaultInstance ?? new Addresses();

+            builderIsReadOnly = true;

             return this;

           }

           

           public override Builder Clone() {

-            return new Builder().MergeFrom(result);

+            if (builderIsReadOnly) {

+              return new Builder(result);

+            } else {

+              return new Builder().MergeFrom(result);

+            }

           }

           

           public override pbd::MessageDescriptor DescriptorForType {

@@ -474,12 +531,11 @@
           }

           

           public override Addresses BuildPartial() {

-            if (result == null) {

-              throw new global::System.InvalidOperationException("build() has already been called on this Builder");

+            if (builderIsReadOnly) {

+              return result;

             }

-            Addresses returnMe = result;

-            result = null;

-            return returnMe;

+            builderIsReadOnly = true;

+            return result;

           }

           

           

@@ -492,11 +548,13 @@
           }

           public Builder SetAddress(string value) {

             pb::ThrowHelper.ThrowIfNull(value, "value");

+            PrepareBuilder();

             result.hasAddress = true;

             result.address_ = value;

             return this;

           }

           public Builder ClearAddress() {

+            PrepareBuilder();

             result.hasAddress = false;

             result.address_ = "";

             return this;

@@ -511,11 +569,13 @@
           }

           public Builder SetAddress2(string value) {

             pb::ThrowHelper.ThrowIfNull(value, "value");

+            PrepareBuilder();

             result.hasAddress2 = true;

             result.address2_ = value;

             return this;

           }

           public Builder ClearAddress2() {

+            PrepareBuilder();

             result.hasAddress2 = false;

             result.address2_ = "";

             return this;

@@ -530,11 +590,13 @@
           }

           public Builder SetCity(string value) {

             pb::ThrowHelper.ThrowIfNull(value, "value");

+            PrepareBuilder();

             result.hasCity = true;

             result.city_ = value;

             return this;

           }

           public Builder ClearCity() {

+            PrepareBuilder();

             result.hasCity = false;

             result.city_ = "";

             return this;

@@ -549,11 +611,13 @@
           }

           public Builder SetState(string value) {

             pb::ThrowHelper.ThrowIfNull(value, "value");

+            PrepareBuilder();

             result.hasState = true;

             result.state_ = value;

             return this;

           }

           public Builder ClearState() {

+            PrepareBuilder();

             result.hasState = false;

             result.state_ = "";

             return this;

@@ -569,11 +633,13 @@
           }

           [global::System.CLSCompliant(false)]

           public Builder SetZip(uint value) {

+            PrepareBuilder();

             result.hasZip = true;

             result.zip_ = value;

             return this;

           }

           public Builder ClearZip() {

+            PrepareBuilder();

             result.hasZip = false;

             result.zip_ = 0;

             return this;

@@ -687,7 +753,7 @@
     public override Builder ToBuilder() { return CreateBuilder(this); }

     public override Builder CreateBuilderForType() { return new Builder(); }

     public static Builder CreateBuilder(TestInteropPerson prototype) {

-      return (Builder) new Builder().MergeFrom(prototype);

+      return new Builder(prototype);

     }

     

     [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]

@@ -697,21 +763,48 @@
       protected override Builder ThisBuilder {

         get { return this; }

       }

-      public Builder() {}

+      public Builder() {

+        result = DefaultInstance ?? new TestInteropPerson();

+        builderIsReadOnly = result == DefaultInstance;

+      }

+      internal Builder(TestInteropPerson cloneFrom) {

+        result = cloneFrom;

+        builderIsReadOnly = true;

+      }

       

-      TestInteropPerson result = new TestInteropPerson();

+      bool builderIsReadOnly;

+      TestInteropPerson result;

+      

+      private TestInteropPerson PrepareBuilder() {

+        if (builderIsReadOnly) {

+          TestInteropPerson original = result;

+          result = new TestInteropPerson();

+          builderIsReadOnly = false;

+          MergeFrom(original);

+        }

+        return result;

+      }

+      

+      public override bool IsInitialized {

+        get { return result.IsInitialized; }

+      }

       

       protected override TestInteropPerson MessageBeingBuilt {

-        get { return result; }

+        get { return PrepareBuilder(); }

       }

       

       public override Builder Clear() {

-        result = new TestInteropPerson();

+        result = DefaultInstance ?? new TestInteropPerson();

+        builderIsReadOnly = true;

         return this;

       }

       

       public override Builder Clone() {

-        return new Builder().MergeFrom(result);

+        if (builderIsReadOnly) {

+          return new Builder(result);

+        } else {

+          return new Builder().MergeFrom(result);

+        }

       }

       

       public override pbd::MessageDescriptor DescriptorForType {

@@ -723,15 +816,14 @@
       }

       

       public override TestInteropPerson BuildPartial() {

-        if (result == null) {

-          throw new global::System.InvalidOperationException("build() has already been called on this Builder");

+        if (builderIsReadOnly) {

+          return result;

         }

         result.codes_.MakeReadOnly();

         result.phone_.MakeReadOnly();

         result.addresses_.MakeReadOnly();

-        TestInteropPerson returnMe = result;

-        result = null;

-        return returnMe;

+        builderIsReadOnly = true;

+        return result;

       }

       

       

@@ -744,11 +836,13 @@
       }

       public Builder SetName(string value) {

         pb::ThrowHelper.ThrowIfNull(value, "value");

+        PrepareBuilder();

         result.hasName = true;

         result.name_ = value;

         return this;

       }

       public Builder ClearName() {

+        PrepareBuilder();

         result.hasName = false;

         result.name_ = "";

         return this;

@@ -762,11 +856,13 @@
         set { SetId(value); }

       }

       public Builder SetId(int value) {

+        PrepareBuilder();

         result.hasId = true;

         result.id_ = value;

         return this;

       }

       public Builder ClearId() {

+        PrepareBuilder();

         result.hasId = false;

         result.id_ = 0;

         return this;

@@ -781,18 +877,20 @@
       }

       public Builder SetEmail(string value) {

         pb::ThrowHelper.ThrowIfNull(value, "value");

+        PrepareBuilder();

         result.hasEmail = true;

         result.email_ = value;

         return this;

       }

       public Builder ClearEmail() {

+        PrepareBuilder();

         result.hasEmail = false;

         result.email_ = "";

         return this;

       }

       

       public pbc::IPopsicleList<int> CodesList {

-        get { return result.codes_; }

+        get { return PrepareBuilder().codes_; }

       }

       public int CodesCount {

         get { return result.CodesCount; }

@@ -801,24 +899,28 @@
         return result.GetCodes(index);

       }

       public Builder SetCodes(int index, int value) {

+        PrepareBuilder();

         result.codes_[index] = value;

         return this;

       }

       public Builder AddCodes(int value) {

+        PrepareBuilder();

         result.codes_.Add(value);

         return this;

       }

       public Builder AddRangeCodes(scg::IEnumerable<int> values) {

+        PrepareBuilder();

         base.AddRange(values, result.codes_);

         return this;

       }

       public Builder ClearCodes() {

+        PrepareBuilder();

         result.codes_.Clear();

         return this;

       }

       

       public pbc::IPopsicleList<global::Google.ProtocolBuffers.TestProtos.TestInteropPerson.Types.PhoneNumber> PhoneList {

-        get { return result.phone_; }

+        get { return PrepareBuilder().phone_; }

       }

       public int PhoneCount {

         get { return result.PhoneCount; }

@@ -828,35 +930,41 @@
       }

       public Builder SetPhone(int index, global::Google.ProtocolBuffers.TestProtos.TestInteropPerson.Types.PhoneNumber value) {

         pb::ThrowHelper.ThrowIfNull(value, "value");

+        PrepareBuilder();

         result.phone_[index] = value;

         return this;

       }

       public Builder SetPhone(int index, global::Google.ProtocolBuffers.TestProtos.TestInteropPerson.Types.PhoneNumber.Builder builderForValue) {

         pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");

+        PrepareBuilder();

         result.phone_[index] = builderForValue.Build();

         return this;

       }

       public Builder AddPhone(global::Google.ProtocolBuffers.TestProtos.TestInteropPerson.Types.PhoneNumber value) {

         pb::ThrowHelper.ThrowIfNull(value, "value");

+        PrepareBuilder();

         result.phone_.Add(value);

         return this;

       }

       public Builder AddPhone(global::Google.ProtocolBuffers.TestProtos.TestInteropPerson.Types.PhoneNumber.Builder builderForValue) {

         pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");

+        PrepareBuilder();

         result.phone_.Add(builderForValue.Build());

         return this;

       }

       public Builder AddRangePhone(scg::IEnumerable<global::Google.ProtocolBuffers.TestProtos.TestInteropPerson.Types.PhoneNumber> values) {

+        PrepareBuilder();

         base.AddRange(values, result.phone_);

         return this;

       }

       public Builder ClearPhone() {

+        PrepareBuilder();

         result.phone_.Clear();

         return this;

       }

       

       public pbc::IPopsicleList<global::Google.ProtocolBuffers.TestProtos.TestInteropPerson.Types.Addresses> AddressesList {

-        get { return result.addresses_; }

+        get { return PrepareBuilder().addresses_; }

       }

       public int AddressesCount {

         get { return result.AddressesCount; }

@@ -866,29 +974,35 @@
       }

       public Builder SetAddresses(int index, global::Google.ProtocolBuffers.TestProtos.TestInteropPerson.Types.Addresses value) {

         pb::ThrowHelper.ThrowIfNull(value, "value");

+        PrepareBuilder();

         result.addresses_[index] = value;

         return this;

       }

       public Builder SetAddresses(int index, global::Google.ProtocolBuffers.TestProtos.TestInteropPerson.Types.Addresses.Builder builderForValue) {

         pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");

+        PrepareBuilder();

         result.addresses_[index] = builderForValue.Build();

         return this;

       }

       public Builder AddAddresses(global::Google.ProtocolBuffers.TestProtos.TestInteropPerson.Types.Addresses value) {

         pb::ThrowHelper.ThrowIfNull(value, "value");

+        PrepareBuilder();

         result.addresses_.Add(value);

         return this;

       }

       public Builder AddAddresses(global::Google.ProtocolBuffers.TestProtos.TestInteropPerson.Types.Addresses.Builder builderForValue) {

         pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");

+        PrepareBuilder();

         result.addresses_.Add(builderForValue.Build());

         return this;

       }

       public Builder AddRangeAddresses(scg::IEnumerable<global::Google.ProtocolBuffers.TestProtos.TestInteropPerson.Types.Addresses> values) {

+        PrepareBuilder();

         base.AddRange(values, result.addresses_);

         return this;

       }

       public Builder ClearAddresses() {

+        PrepareBuilder();

         result.addresses_.Clear();

         return this;

       }

@@ -967,7 +1081,7 @@
     public override Builder ToBuilder() { return CreateBuilder(this); }

     public override Builder CreateBuilderForType() { return new Builder(); }

     public static Builder CreateBuilder(TestInteropEmployeeId prototype) {

-      return (Builder) new Builder().MergeFrom(prototype);

+      return new Builder(prototype);

     }

     

     [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]

@@ -977,21 +1091,48 @@
       protected override Builder ThisBuilder {

         get { return this; }

       }

-      public Builder() {}

+      public Builder() {

+        result = DefaultInstance ?? new TestInteropEmployeeId();

+        builderIsReadOnly = result == DefaultInstance;

+      }

+      internal Builder(TestInteropEmployeeId cloneFrom) {

+        result = cloneFrom;

+        builderIsReadOnly = true;

+      }

       

-      TestInteropEmployeeId result = new TestInteropEmployeeId();

+      bool builderIsReadOnly;

+      TestInteropEmployeeId result;

+      

+      private TestInteropEmployeeId PrepareBuilder() {

+        if (builderIsReadOnly) {

+          TestInteropEmployeeId original = result;

+          result = new TestInteropEmployeeId();

+          builderIsReadOnly = false;

+          MergeFrom(original);

+        }

+        return result;

+      }

+      

+      public override bool IsInitialized {

+        get { return result.IsInitialized; }

+      }

       

       protected override TestInteropEmployeeId MessageBeingBuilt {

-        get { return result; }

+        get { return PrepareBuilder(); }

       }

       

       public override Builder Clear() {

-        result = new TestInteropEmployeeId();

+        result = DefaultInstance ?? new TestInteropEmployeeId();

+        builderIsReadOnly = true;

         return this;

       }

       

       public override Builder Clone() {

-        return new Builder().MergeFrom(result);

+        if (builderIsReadOnly) {

+          return new Builder(result);

+        } else {

+          return new Builder().MergeFrom(result);

+        }

       }

       

       public override pbd::MessageDescriptor DescriptorForType {

@@ -1003,12 +1144,11 @@
       }

       

       public override TestInteropEmployeeId BuildPartial() {

-        if (result == null) {

-          throw new global::System.InvalidOperationException("build() has already been called on this Builder");

+        if (builderIsReadOnly) {

+          return result;

         }

-        TestInteropEmployeeId returnMe = result;

-        result = null;

-        return returnMe;

+        builderIsReadOnly = true;

+        return result;

       }

       

       

@@ -1021,11 +1161,13 @@
       }

       public Builder SetNumber(string value) {

         pb::ThrowHelper.ThrowIfNull(value, "value");

+        PrepareBuilder();

         result.hasNumber = true;

         result.number_ = value;

         return this;

       }

       public Builder ClearNumber() {

+        PrepareBuilder();

         result.hasNumber = false;

         result.number_ = "";

         return this;

@@ -1147,7 +1289,7 @@
         public override Builder ToBuilder() { return CreateBuilder(this); }

         public override Builder CreateBuilderForType() { return new Builder(); }

         public static Builder CreateBuilder(SubA prototype) {

-          return (Builder) new Builder().MergeFrom(prototype);

+          return new Builder(prototype);

         }

         

         [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]

@@ -1157,21 +1299,48 @@
           protected override Builder ThisBuilder {

             get { return this; }

           }

-          public Builder() {}

+          public Builder() {

+            result = DefaultInstance ?? new SubA();

+            builderIsReadOnly = result == DefaultInstance;

+          }

+          internal Builder(SubA cloneFrom) {

+            result = cloneFrom;

+            builderIsReadOnly = true;

+          }

           

-          SubA result = new SubA();

+          bool builderIsReadOnly;

+          SubA result;

+          

+          private SubA PrepareBuilder() {

+            if (builderIsReadOnly) {

+              SubA original = result;

+              result = new SubA();

+              builderIsReadOnly = false;

+              MergeFrom(original);

+            }

+            return result;

+          }

+          

+          public override bool IsInitialized {

+            get { return result.IsInitialized; }

+          }

           

           protected override SubA MessageBeingBuilt {

-            get { return result; }

+            get { return PrepareBuilder(); }

           }

           

           public override Builder Clear() {

-            result = new SubA();

+            result = DefaultInstance ?? new SubA();

+            builderIsReadOnly = true;

             return this;

           }

           

           public override Builder Clone() {

-            return new Builder().MergeFrom(result);

+            if (builderIsReadOnly) {

+              return new Builder(result);

+            } else {

+              return new Builder().MergeFrom(result);

+            }

           }

           

           public override pbd::MessageDescriptor DescriptorForType {

@@ -1183,13 +1352,12 @@
           }

           

           public override SubA BuildPartial() {

-            if (result == null) {

-              throw new global::System.InvalidOperationException("build() has already been called on this Builder");

+            if (builderIsReadOnly) {

+              return result;

             }

             result.values_.MakeReadOnly();

-            SubA returnMe = result;

-            result = null;

-            return returnMe;

+            builderIsReadOnly = true;

+            return result;

           }

           

           

@@ -1201,18 +1369,20 @@
             set { SetCount(value); }

           }

           public Builder SetCount(int value) {

+            PrepareBuilder();

             result.hasCount = true;

             result.count_ = value;

             return this;

           }

           public Builder ClearCount() {

+            PrepareBuilder();

             result.hasCount = false;

             result.count_ = 0;

             return this;

           }

           

           public pbc::IPopsicleList<string> ValuesList {

-            get { return result.values_; }

+            get { return PrepareBuilder().values_; }

           }

           public int ValuesCount {

             get { return result.ValuesCount; }

@@ -1222,19 +1392,23 @@
           }

           public Builder SetValues(int index, string value) {

             pb::ThrowHelper.ThrowIfNull(value, "value");

+            PrepareBuilder();

             result.values_[index] = value;

             return this;

           }

           public Builder AddValues(string value) {

             pb::ThrowHelper.ThrowIfNull(value, "value");

+            PrepareBuilder();

             result.values_.Add(value);

             return this;

           }

           public Builder AddRangeValues(scg::IEnumerable<string> values) {

+            PrepareBuilder();

             base.AddRange(values, result.values_);

             return this;

           }

           public Builder ClearValues() {

+            PrepareBuilder();

             result.values_.Clear();

             return this;

           }

@@ -1321,7 +1495,7 @@
     public override Builder ToBuilder() { return CreateBuilder(this); }

     public override Builder CreateBuilderForType() { return new Builder(); }

     public static Builder CreateBuilder(TestMissingFieldsA prototype) {

-      return (Builder) new Builder().MergeFrom(prototype);

+      return new Builder(prototype);

     }

     

     [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]

@@ -1331,21 +1505,48 @@
       protected override Builder ThisBuilder {

         get { return this; }

       }

-      public Builder() {}

+      public Builder() {

+        result = DefaultInstance ?? new TestMissingFieldsA();

+        builderIsReadOnly = result == DefaultInstance;

+      }

+      internal Builder(TestMissingFieldsA cloneFrom) {

+        result = cloneFrom;

+        builderIsReadOnly = true;

+      }

       

-      TestMissingFieldsA result = new TestMissingFieldsA();

+      bool builderIsReadOnly;

+      TestMissingFieldsA result;

+      

+      private TestMissingFieldsA PrepareBuilder() {

+        if (builderIsReadOnly) {

+          TestMissingFieldsA original = result;

+          result = new TestMissingFieldsA();

+          builderIsReadOnly = false;

+          MergeFrom(original);

+        }

+        return result;

+      }

+      

+      public override bool IsInitialized {

+        get { return result.IsInitialized; }

+      }

       

       protected override TestMissingFieldsA MessageBeingBuilt {

-        get { return result; }

+        get { return PrepareBuilder(); }

       }

       

       public override Builder Clear() {

-        result = new TestMissingFieldsA();

+        result = DefaultInstance ?? new TestMissingFieldsA();

+        builderIsReadOnly = true;

         return this;

       }

       

       public override Builder Clone() {

-        return new Builder().MergeFrom(result);

+        if (builderIsReadOnly) {

+          return new Builder(result);

+        } else {

+          return new Builder().MergeFrom(result);

+        }

       }

       

       public override pbd::MessageDescriptor DescriptorForType {

@@ -1357,12 +1558,11 @@
       }

       

       public override TestMissingFieldsA BuildPartial() {

-        if (result == null) {

-          throw new global::System.InvalidOperationException("build() has already been called on this Builder");

+        if (builderIsReadOnly) {

+          return result;

         }

-        TestMissingFieldsA returnMe = result;

-        result = null;

-        return returnMe;

+        builderIsReadOnly = true;

+        return result;

       }

       

       

@@ -1375,11 +1575,13 @@
       }

       public Builder SetName(string value) {

         pb::ThrowHelper.ThrowIfNull(value, "value");

+        PrepareBuilder();

         result.hasName = true;

         result.name_ = value;

         return this;

       }

       public Builder ClearName() {

+        PrepareBuilder();

         result.hasName = false;

         result.name_ = "";

         return this;

@@ -1393,11 +1595,13 @@
         set { SetId(value); }

       }

       public Builder SetId(int value) {

+        PrepareBuilder();

         result.hasId = true;

         result.id_ = value;

         return this;

       }

       public Builder ClearId() {

+        PrepareBuilder();

         result.hasId = false;

         result.id_ = 0;

         return this;

@@ -1412,11 +1616,13 @@
       }

       public Builder SetEmail(string value) {

         pb::ThrowHelper.ThrowIfNull(value, "value");

+        PrepareBuilder();

         result.hasEmail = true;

         result.email_ = value;

         return this;

       }

       public Builder ClearEmail() {

+        PrepareBuilder();

         result.hasEmail = false;

         result.email_ = "";

         return this;

@@ -1431,18 +1637,21 @@
       }

       public Builder SetTestA(global::Google.ProtocolBuffers.TestProtos.TestMissingFieldsA.Types.SubA value) {

         pb::ThrowHelper.ThrowIfNull(value, "value");

+        PrepareBuilder();

         result.hasTestA = true;

         result.testA_ = value;

         return this;

       }

       public Builder SetTestA(global::Google.ProtocolBuffers.TestProtos.TestMissingFieldsA.Types.SubA.Builder builderForValue) {

         pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");

+        PrepareBuilder();

         result.hasTestA = true;

         result.testA_ = builderForValue.Build();

         return this;

       }

       public Builder MergeTestA(global::Google.ProtocolBuffers.TestProtos.TestMissingFieldsA.Types.SubA value) {

         pb::ThrowHelper.ThrowIfNull(value, "value");

+        PrepareBuilder();

         if (result.hasTestA &&

             result.testA_ != global::Google.ProtocolBuffers.TestProtos.TestMissingFieldsA.Types.SubA.DefaultInstance) {

             result.testA_ = global::Google.ProtocolBuffers.TestProtos.TestMissingFieldsA.Types.SubA.CreateBuilder(result.testA_).MergeFrom(value).BuildPartial();

@@ -1453,6 +1662,7 @@
         return this;

       }

       public Builder ClearTestA() {

+        PrepareBuilder();

         result.hasTestA = false;

         result.testA_ = global::Google.ProtocolBuffers.TestProtos.TestMissingFieldsA.Types.SubA.DefaultInstance;

         return this;

@@ -1564,7 +1774,7 @@
         public override Builder ToBuilder() { return CreateBuilder(this); }

         public override Builder CreateBuilderForType() { return new Builder(); }

         public static Builder CreateBuilder(SubB prototype) {

-          return (Builder) new Builder().MergeFrom(prototype);

+          return new Builder(prototype);

         }

         

         [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]

@@ -1574,21 +1784,48 @@
           protected override Builder ThisBuilder {

             get { return this; }

           }

-          public Builder() {}

+          public Builder() {

+            result = DefaultInstance ?? new SubB();

+            builderIsReadOnly = result == DefaultInstance;

+          }

+          internal Builder(SubB cloneFrom) {

+            result = cloneFrom;

+            builderIsReadOnly = true;

+          }

           

-          SubB result = new SubB();

+          bool builderIsReadOnly;

+          SubB result;

+          

+          private SubB PrepareBuilder() {

+            if (builderIsReadOnly) {

+              SubB original = result;

+              result = new SubB();

+              builderIsReadOnly = false;

+              MergeFrom(original);

+            }

+            return result;

+          }

+          

+          public override bool IsInitialized {

+            get { return result.IsInitialized; }

+          }

           

           protected override SubB MessageBeingBuilt {

-            get { return result; }

+            get { return PrepareBuilder(); }

           }

           

           public override Builder Clear() {

-            result = new SubB();

+            result = DefaultInstance ?? new SubB();

+            builderIsReadOnly = true;

             return this;

           }

           

           public override Builder Clone() {

-            return new Builder().MergeFrom(result);

+            if (builderIsReadOnly) {

+              return new Builder(result);

+            } else {

+              return new Builder().MergeFrom(result);

+            }

           }

           

           public override pbd::MessageDescriptor DescriptorForType {

@@ -1600,18 +1837,17 @@
           }

           

           public override SubB BuildPartial() {

-            if (result == null) {

-              throw new global::System.InvalidOperationException("build() has already been called on this Builder");

+            if (builderIsReadOnly) {

+              return result;

             }

             result.values_.MakeReadOnly();

-            SubB returnMe = result;

-            result = null;

-            return returnMe;

+            builderIsReadOnly = true;

+            return result;

           }

           

           

           public pbc::IPopsicleList<string> ValuesList {

-            get { return result.values_; }

+            get { return PrepareBuilder().values_; }

           }

           public int ValuesCount {

             get { return result.ValuesCount; }

@@ -1621,19 +1857,23 @@
           }

           public Builder SetValues(int index, string value) {

             pb::ThrowHelper.ThrowIfNull(value, "value");

+            PrepareBuilder();

             result.values_[index] = value;

             return this;

           }

           public Builder AddValues(string value) {

             pb::ThrowHelper.ThrowIfNull(value, "value");

+            PrepareBuilder();

             result.values_.Add(value);

             return this;

           }

           public Builder AddRangeValues(scg::IEnumerable<string> values) {

+            PrepareBuilder();

             base.AddRange(values, result.values_);

             return this;

           }

           public Builder ClearValues() {

+            PrepareBuilder();

             result.values_.Clear();

             return this;

           }

@@ -1720,7 +1960,7 @@
     public override Builder ToBuilder() { return CreateBuilder(this); }

     public override Builder CreateBuilderForType() { return new Builder(); }

     public static Builder CreateBuilder(TestMissingFieldsB prototype) {

-      return (Builder) new Builder().MergeFrom(prototype);

+      return new Builder(prototype);

     }

     

     [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]

@@ -1730,21 +1970,48 @@
       protected override Builder ThisBuilder {

         get { return this; }

       }

-      public Builder() {}

+      public Builder() {

+        result = DefaultInstance ?? new TestMissingFieldsB();

+        builderIsReadOnly = result == DefaultInstance;

+      }

+      internal Builder(TestMissingFieldsB cloneFrom) {

+        result = cloneFrom;

+        builderIsReadOnly = true;

+      }

       

-      TestMissingFieldsB result = new TestMissingFieldsB();

+      bool builderIsReadOnly;

+      TestMissingFieldsB result;

+      

+      private TestMissingFieldsB PrepareBuilder() {

+        if (builderIsReadOnly) {

+          TestMissingFieldsB original = result;

+          result = new TestMissingFieldsB();

+          builderIsReadOnly = false;

+          MergeFrom(original);

+        }

+        return result;

+      }

+      

+      public override bool IsInitialized {

+        get { return result.IsInitialized; }

+      }

       

       protected override TestMissingFieldsB MessageBeingBuilt {

-        get { return result; }

+        get { return PrepareBuilder(); }

       }

       

       public override Builder Clear() {

-        result = new TestMissingFieldsB();

+        result = DefaultInstance ?? new TestMissingFieldsB();

+        builderIsReadOnly = true;

         return this;

       }

       

       public override Builder Clone() {

-        return new Builder().MergeFrom(result);

+        if (builderIsReadOnly) {

+          return new Builder(result);

+        } else {

+          return new Builder().MergeFrom(result);

+        }

       }

       

       public override pbd::MessageDescriptor DescriptorForType {

@@ -1756,12 +2023,11 @@
       }

       

       public override TestMissingFieldsB BuildPartial() {

-        if (result == null) {

-          throw new global::System.InvalidOperationException("build() has already been called on this Builder");

+        if (builderIsReadOnly) {

+          return result;

         }

-        TestMissingFieldsB returnMe = result;

-        result = null;

-        return returnMe;

+        builderIsReadOnly = true;

+        return result;

       }

       

       

@@ -1774,11 +2040,13 @@
       }

       public Builder SetName(string value) {

         pb::ThrowHelper.ThrowIfNull(value, "value");

+        PrepareBuilder();

         result.hasName = true;

         result.name_ = value;

         return this;

       }

       public Builder ClearName() {

+        PrepareBuilder();

         result.hasName = false;

         result.name_ = "";

         return this;

@@ -1792,11 +2060,13 @@
         set { SetId(value); }

       }

       public Builder SetId(int value) {

+        PrepareBuilder();

         result.hasId = true;

         result.id_ = value;

         return this;

       }

       public Builder ClearId() {

+        PrepareBuilder();

         result.hasId = false;

         result.id_ = 0;

         return this;

@@ -1811,11 +2081,13 @@
       }

       public Builder SetWebsite(string value) {

         pb::ThrowHelper.ThrowIfNull(value, "value");

+        PrepareBuilder();

         result.hasWebsite = true;

         result.website_ = value;

         return this;

       }

       public Builder ClearWebsite() {

+        PrepareBuilder();

         result.hasWebsite = false;

         result.website_ = "";

         return this;

@@ -1830,18 +2102,21 @@
       }

       public Builder SetTestB(global::Google.ProtocolBuffers.TestProtos.TestMissingFieldsB.Types.SubB value) {

         pb::ThrowHelper.ThrowIfNull(value, "value");

+        PrepareBuilder();

         result.hasTestB = true;

         result.testB_ = value;

         return this;

       }

       public Builder SetTestB(global::Google.ProtocolBuffers.TestProtos.TestMissingFieldsB.Types.SubB.Builder builderForValue) {

         pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");

+        PrepareBuilder();

         result.hasTestB = true;

         result.testB_ = builderForValue.Build();

         return this;

       }

       public Builder MergeTestB(global::Google.ProtocolBuffers.TestProtos.TestMissingFieldsB.Types.SubB value) {

         pb::ThrowHelper.ThrowIfNull(value, "value");

+        PrepareBuilder();

         if (result.hasTestB &&

             result.testB_ != global::Google.ProtocolBuffers.TestProtos.TestMissingFieldsB.Types.SubB.DefaultInstance) {

             result.testB_ = global::Google.ProtocolBuffers.TestProtos.TestMissingFieldsB.Types.SubB.CreateBuilder(result.testB_).MergeFrom(value).BuildPartial();

@@ -1852,6 +2127,7 @@
         return this;

       }

       public Builder ClearTestB() {

+        PrepareBuilder();

         result.hasTestB = false;

         result.testB_ = global::Google.ProtocolBuffers.TestProtos.TestMissingFieldsB.Types.SubB.DefaultInstance;

         return this;