First pass at implementation and testing of reusable builders.
diff --git a/src/ProtocolBuffers/DescriptorProtos/CSharpOptions.cs b/src/ProtocolBuffers/DescriptorProtos/CSharpOptions.cs
index 853b0e7..0d9109a 100644
--- a/src/ProtocolBuffers/DescriptorProtos/CSharpOptions.cs
+++ b/src/ProtocolBuffers/DescriptorProtos/CSharpOptions.cs
@@ -415,7 +415,7 @@
     public override Builder ToBuilder() { return CreateBuilder(this); }

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

     public static Builder CreateBuilder(CSharpFileOptions prototype) {

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

+      return new Builder(prototype);

     }

     

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

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

         get { return this; }

       }

-      public Builder() {}

+      public Builder() {

+        result = DefaultInstance ?? new CSharpFileOptions();

+        builderIsReadOnly = result == DefaultInstance;

+      }

+      internal Builder(CSharpFileOptions cloneFrom) {

+        result = cloneFrom;

+        builderIsReadOnly = true;

+      }

       

-      CSharpFileOptions result = new CSharpFileOptions();

+      bool builderIsReadOnly;

+      CSharpFileOptions result;

+      

+      private CSharpFileOptions PrepareBuilder() {

+        if (builderIsReadOnly) {

+          CSharpFileOptions original = result;

+          result = new CSharpFileOptions();

+          builderIsReadOnly = false;

+          MergeFrom(original);

+        }

+        return result;

+      }

+      

+      public override bool IsInitialized {

+        get { return result.IsInitialized; }

+      }

       

       protected override CSharpFileOptions MessageBeingBuilt {

-        get { return result; }

+        get { return PrepareBuilder(); }

       }

       

       public override Builder Clear() {

-        result = new CSharpFileOptions();

+        result = DefaultInstance ?? new CSharpFileOptions();

+        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 {

@@ -451,12 +478,11 @@
       }

       

       public override CSharpFileOptions BuildPartial() {

-        if (result == null) {

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

+        if (builderIsReadOnly) {

+          return result;

         }

-        CSharpFileOptions returnMe = result;

-        result = null;

-        return returnMe;

+        builderIsReadOnly = true;

+        return result;

       }

       

       public override Builder MergeFrom(pb::IMessage other) {

@@ -470,6 +496,7 @@
       

       public override Builder MergeFrom(CSharpFileOptions other) {

         if (other == global::Google.ProtocolBuffers.DescriptorProtos.CSharpFileOptions.DefaultInstance) return this;

+        PrepareBuilder();

         if (other.HasNamespace) {

           Namespace = other.Namespace;

         }

@@ -518,6 +545,7 @@
       }

       

       public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {

+        PrepareBuilder();

         pb::UnknownFieldSet.Builder unknownFields = null;

         uint tag;

         string field_name;

@@ -630,11 +658,13 @@
       }

       public Builder SetNamespace(string value) {

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

+        PrepareBuilder();

         result.hasNamespace = true;

         result.namespace_ = value;

         return this;

       }

       public Builder ClearNamespace() {

+        PrepareBuilder();

         result.hasNamespace = false;

         result.namespace_ = "";

         return this;

@@ -649,11 +679,13 @@
       }

       public Builder SetUmbrellaClassname(string value) {

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

+        PrepareBuilder();

         result.hasUmbrellaClassname = true;

         result.umbrellaClassname_ = value;

         return this;

       }

       public Builder ClearUmbrellaClassname() {

+        PrepareBuilder();

         result.hasUmbrellaClassname = false;

         result.umbrellaClassname_ = "";

         return this;

@@ -667,11 +699,13 @@
         set { SetPublicClasses(value); }

       }

       public Builder SetPublicClasses(bool value) {

+        PrepareBuilder();

         result.hasPublicClasses = true;

         result.publicClasses_ = value;

         return this;

       }

       public Builder ClearPublicClasses() {

+        PrepareBuilder();

         result.hasPublicClasses = false;

         result.publicClasses_ = true;

         return this;

@@ -685,11 +719,13 @@
         set { SetMultipleFiles(value); }

       }

       public Builder SetMultipleFiles(bool value) {

+        PrepareBuilder();

         result.hasMultipleFiles = true;

         result.multipleFiles_ = value;

         return this;

       }

       public Builder ClearMultipleFiles() {

+        PrepareBuilder();

         result.hasMultipleFiles = false;

         result.multipleFiles_ = false;

         return this;

@@ -703,11 +739,13 @@
         set { SetNestClasses(value); }

       }

       public Builder SetNestClasses(bool value) {

+        PrepareBuilder();

         result.hasNestClasses = true;

         result.nestClasses_ = value;

         return this;

       }

       public Builder ClearNestClasses() {

+        PrepareBuilder();

         result.hasNestClasses = false;

         result.nestClasses_ = false;

         return this;

@@ -721,11 +759,13 @@
         set { SetCodeContracts(value); }

       }

       public Builder SetCodeContracts(bool value) {

+        PrepareBuilder();

         result.hasCodeContracts = true;

         result.codeContracts_ = value;

         return this;

       }

       public Builder ClearCodeContracts() {

+        PrepareBuilder();

         result.hasCodeContracts = false;

         result.codeContracts_ = false;

         return this;

@@ -739,11 +779,13 @@
         set { SetExpandNamespaceDirectories(value); }

       }

       public Builder SetExpandNamespaceDirectories(bool value) {

+        PrepareBuilder();

         result.hasExpandNamespaceDirectories = true;

         result.expandNamespaceDirectories_ = value;

         return this;

       }

       public Builder ClearExpandNamespaceDirectories() {

+        PrepareBuilder();

         result.hasExpandNamespaceDirectories = false;

         result.expandNamespaceDirectories_ = false;

         return this;

@@ -757,11 +799,13 @@
         set { SetClsCompliance(value); }

       }

       public Builder SetClsCompliance(bool value) {

+        PrepareBuilder();

         result.hasClsCompliance = true;

         result.clsCompliance_ = value;

         return this;

       }

       public Builder ClearClsCompliance() {

+        PrepareBuilder();

         result.hasClsCompliance = false;

         result.clsCompliance_ = true;

         return this;

@@ -776,11 +820,13 @@
       }

       public Builder SetFileExtension(string value) {

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

+        PrepareBuilder();

         result.hasFileExtension = true;

         result.fileExtension_ = value;

         return this;

       }

       public Builder ClearFileExtension() {

+        PrepareBuilder();

         result.hasFileExtension = false;

         result.fileExtension_ = ".cs";

         return this;

@@ -795,11 +841,13 @@
       }

       public Builder SetUmbrellaNamespace(string value) {

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

+        PrepareBuilder();

         result.hasUmbrellaNamespace = true;

         result.umbrellaNamespace_ = value;

         return this;

       }

       public Builder ClearUmbrellaNamespace() {

+        PrepareBuilder();

         result.hasUmbrellaNamespace = false;

         result.umbrellaNamespace_ = "";

         return this;

@@ -814,11 +862,13 @@
       }

       public Builder SetOutputDirectory(string value) {

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

+        PrepareBuilder();

         result.hasOutputDirectory = true;

         result.outputDirectory_ = value;

         return this;

       }

       public Builder ClearOutputDirectory() {

+        PrepareBuilder();

         result.hasOutputDirectory = false;

         result.outputDirectory_ = ".";

         return this;

@@ -832,11 +882,13 @@
         set { SetIgnoreGoogleProtobuf(value); }

       }

       public Builder SetIgnoreGoogleProtobuf(bool value) {

+        PrepareBuilder();

         result.hasIgnoreGoogleProtobuf = true;

         result.ignoreGoogleProtobuf_ = value;

         return this;

       }

       public Builder ClearIgnoreGoogleProtobuf() {

+        PrepareBuilder();

         result.hasIgnoreGoogleProtobuf = false;

         result.ignoreGoogleProtobuf_ = false;

         return this;

@@ -850,11 +902,13 @@
         set { SetServiceGeneratorType(value); }

       }

       public Builder SetServiceGeneratorType(global::Google.ProtocolBuffers.DescriptorProtos.CSharpServiceType value) {

+        PrepareBuilder();

         result.hasServiceGeneratorType = true;

         result.serviceGeneratorType_ = value;

         return this;

       }

       public Builder ClearServiceGeneratorType() {

+        PrepareBuilder();

         result.hasServiceGeneratorType = false;

         result.serviceGeneratorType_ = global::Google.ProtocolBuffers.DescriptorProtos.CSharpServiceType.NONE;

         return this;

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

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

     public static Builder CreateBuilder(CSharpFieldOptions prototype) {

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

+      return new Builder(prototype);

     }

     

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

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

         get { return this; }

       }

-      public Builder() {}

+      public Builder() {

+        result = DefaultInstance ?? new CSharpFieldOptions();

+        builderIsReadOnly = result == DefaultInstance;

+      }

+      internal Builder(CSharpFieldOptions cloneFrom) {

+        result = cloneFrom;

+        builderIsReadOnly = true;

+      }

       

-      CSharpFieldOptions result = new CSharpFieldOptions();

+      bool builderIsReadOnly;

+      CSharpFieldOptions result;

+      

+      private CSharpFieldOptions PrepareBuilder() {

+        if (builderIsReadOnly) {

+          CSharpFieldOptions original = result;

+          result = new CSharpFieldOptions();

+          builderIsReadOnly = false;

+          MergeFrom(original);

+        }

+        return result;

+      }

+      

+      public override bool IsInitialized {

+        get { return result.IsInitialized; }

+      }

       

       protected override CSharpFieldOptions MessageBeingBuilt {

-        get { return result; }

+        get { return PrepareBuilder(); }

       }

       

       public override Builder Clear() {

-        result = new CSharpFieldOptions();

+        result = DefaultInstance ?? new CSharpFieldOptions();

+        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 +1084,11 @@
       }

       

       public override CSharpFieldOptions BuildPartial() {

-        if (result == null) {

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

+        if (builderIsReadOnly) {

+          return result;

         }

-        CSharpFieldOptions returnMe = result;

-        result = null;

-        return returnMe;

+        builderIsReadOnly = true;

+        return result;

       }

       

       public override Builder MergeFrom(pb::IMessage other) {

@@ -1022,6 +1102,7 @@
       

       public override Builder MergeFrom(CSharpFieldOptions other) {

         if (other == global::Google.ProtocolBuffers.DescriptorProtos.CSharpFieldOptions.DefaultInstance) return this;

+        PrepareBuilder();

         if (other.HasPropertyName) {

           PropertyName = other.PropertyName;

         }

@@ -1034,6 +1115,7 @@
       }

       

       public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {

+        PrepareBuilder();

         pb::UnknownFieldSet.Builder unknownFields = null;

         uint tag;

         string field_name;

@@ -1090,11 +1172,13 @@
       }

       public Builder SetPropertyName(string value) {

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

+        PrepareBuilder();

         result.hasPropertyName = true;

         result.propertyName_ = value;

         return this;

       }

       public Builder ClearPropertyName() {

+        PrepareBuilder();

         result.hasPropertyName = false;

         result.propertyName_ = "";

         return this;

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

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

     public static Builder CreateBuilder(CSharpServiceOptions prototype) {

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

+      return new Builder(prototype);

     }

     

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

@@ -1217,21 +1301,48 @@
       protected override Builder ThisBuilder {

         get { return this; }

       }

-      public Builder() {}

+      public Builder() {

+        result = DefaultInstance ?? new CSharpServiceOptions();

+        builderIsReadOnly = result == DefaultInstance;

+      }

+      internal Builder(CSharpServiceOptions cloneFrom) {

+        result = cloneFrom;

+        builderIsReadOnly = true;

+      }

       

-      CSharpServiceOptions result = new CSharpServiceOptions();

+      bool builderIsReadOnly;

+      CSharpServiceOptions result;

+      

+      private CSharpServiceOptions PrepareBuilder() {

+        if (builderIsReadOnly) {

+          CSharpServiceOptions original = result;

+          result = new CSharpServiceOptions();

+          builderIsReadOnly = false;

+          MergeFrom(original);

+        }

+        return result;

+      }

+      

+      public override bool IsInitialized {

+        get { return result.IsInitialized; }

+      }

       

       protected override CSharpServiceOptions MessageBeingBuilt {

-        get { return result; }

+        get { return PrepareBuilder(); }

       }

       

       public override Builder Clear() {

-        result = new CSharpServiceOptions();

+        result = DefaultInstance ?? new CSharpServiceOptions();

+        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 {

@@ -1243,12 +1354,11 @@
       }

       

       public override CSharpServiceOptions BuildPartial() {

-        if (result == null) {

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

+        if (builderIsReadOnly) {

+          return result;

         }

-        CSharpServiceOptions returnMe = result;

-        result = null;

-        return returnMe;

+        builderIsReadOnly = true;

+        return result;

       }

       

       public override Builder MergeFrom(pb::IMessage other) {

@@ -1262,6 +1372,7 @@
       

       public override Builder MergeFrom(CSharpServiceOptions other) {

         if (other == global::Google.ProtocolBuffers.DescriptorProtos.CSharpServiceOptions.DefaultInstance) return this;

+        PrepareBuilder();

         if (other.HasInterfaceId) {

           InterfaceId = other.InterfaceId;

         }

@@ -1274,6 +1385,7 @@
       }

       

       public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {

+        PrepareBuilder();

         pb::UnknownFieldSet.Builder unknownFields = null;

         uint tag;

         string field_name;

@@ -1330,11 +1442,13 @@
       }

       public Builder SetInterfaceId(string value) {

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

+        PrepareBuilder();

         result.hasInterfaceId = true;

         result.interfaceId_ = value;

         return this;

       }

       public Builder ClearInterfaceId() {

+        PrepareBuilder();

         result.hasInterfaceId = false;

         result.interfaceId_ = "";

         return this;

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

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

     public static Builder CreateBuilder(CSharpMethodOptions prototype) {

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

+      return new Builder(prototype);

     }

     

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

@@ -1457,21 +1571,48 @@
       protected override Builder ThisBuilder {

         get { return this; }

       }

-      public Builder() {}

+      public Builder() {

+        result = DefaultInstance ?? new CSharpMethodOptions();

+        builderIsReadOnly = result == DefaultInstance;

+      }

+      internal Builder(CSharpMethodOptions cloneFrom) {

+        result = cloneFrom;

+        builderIsReadOnly = true;

+      }

       

-      CSharpMethodOptions result = new CSharpMethodOptions();

+      bool builderIsReadOnly;

+      CSharpMethodOptions result;

+      

+      private CSharpMethodOptions PrepareBuilder() {

+        if (builderIsReadOnly) {

+          CSharpMethodOptions original = result;

+          result = new CSharpMethodOptions();

+          builderIsReadOnly = false;

+          MergeFrom(original);

+        }

+        return result;

+      }

+      

+      public override bool IsInitialized {

+        get { return result.IsInitialized; }

+      }

       

       protected override CSharpMethodOptions MessageBeingBuilt {

-        get { return result; }

+        get { return PrepareBuilder(); }

       }

       

       public override Builder Clear() {

-        result = new CSharpMethodOptions();

+        result = DefaultInstance ?? new CSharpMethodOptions();

+        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 {

@@ -1483,12 +1624,11 @@
       }

       

       public override CSharpMethodOptions BuildPartial() {

-        if (result == null) {

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

+        if (builderIsReadOnly) {

+          return result;

         }

-        CSharpMethodOptions returnMe = result;

-        result = null;

-        return returnMe;

+        builderIsReadOnly = true;

+        return result;

       }

       

       public override Builder MergeFrom(pb::IMessage other) {

@@ -1502,6 +1642,7 @@
       

       public override Builder MergeFrom(CSharpMethodOptions other) {

         if (other == global::Google.ProtocolBuffers.DescriptorProtos.CSharpMethodOptions.DefaultInstance) return this;

+        PrepareBuilder();

         if (other.HasDispatchId) {

           DispatchId = other.DispatchId;

         }

@@ -1514,6 +1655,7 @@
       }

       

       public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {

+        PrepareBuilder();

         pb::UnknownFieldSet.Builder unknownFields = null;

         uint tag;

         string field_name;

@@ -1569,11 +1711,13 @@
         set { SetDispatchId(value); }

       }

       public Builder SetDispatchId(int value) {

+        PrepareBuilder();

         result.hasDispatchId = true;

         result.dispatchId_ = value;

         return this;

       }

       public Builder ClearDispatchId() {

+        PrepareBuilder();

         result.hasDispatchId = false;

         result.dispatchId_ = 0;

         return this;