First pass at benchmarking for C#
diff --git a/benchmarks/README.md b/benchmarks/README.md
index 486b2f9..9711fa1 100644
--- a/benchmarks/README.md
+++ b/benchmarks/README.md
@@ -65,6 +65,12 @@
 ### Node.js
 Node.js benchmark need [node](https://nodejs.org/en/)(higher than V6) and [npm](https://www.npmjs.com/) package manager installed. This benchmark is using the [benchmark](https://www.npmjs.com/package/benchmark) framework to test, which needn't to manually install. And another prerequisite is [protobuf js](https://github.com/protocolbuffers/protobuf/tree/master/js), which needn't to manually install either
 
+### C#
+The C# benchmark code is built as part of the main Google.Protobuf
+solution. It requires the .NET Core SDK, and depends on
+[BenchmarkDotNet](https://github.com/dotnet/BenchmarkDotNet), which
+will be downloaded automatically.
+
 ### Big data
 
 There's some optional big testing data which is not included in the directory
@@ -74,7 +80,7 @@
 $ ./download_data.sh
 ```
 
-After doing this the big data file will automaticly generated in the
+After doing this the big data file will automatically generated in the
 benchmark directory.
 
 ## Run instructions
@@ -209,6 +215,15 @@
 $ ./js-benchmark $(specific generated dataset file name)
 ```
 
+### C#
+From `csharp/src/Google.Protobuf.Benchmarks`, run:
+
+```
+$ dotnet run -c Release
+```
+
+We intend to add support for this within the makefile in due course.
+
 ## Benchmark datasets
 
 Each data set is in the format of benchmarks.proto:
diff --git a/csharp/.gitignore b/csharp/.gitignore
index 8ba8849..d0d7ae0 100644
--- a/csharp/.gitignore
+++ b/csharp/.gitignore
@@ -29,3 +29,6 @@
 mono/*.dll
 lib/protoc.exe
 *.ncrunch*
+
+# Benchmark output
+BenchmarkDotNet.Artifacts/
diff --git a/csharp/generate_protos.sh b/csharp/generate_protos.sh
index 31a4b90..5d3f5b7 100755
--- a/csharp/generate_protos.sh
+++ b/csharp/generate_protos.sh
@@ -61,3 +61,9 @@
 
 $PROTOC -Iconformance -Isrc --csharp_out=csharp/src/Google.Protobuf.Conformance \
     conformance/conformance.proto
+
+# Benchmark protos
+$PROTOC -Ibenchmarks \
+  benchmarks/datasets/google_message1/proto3/*.proto \
+  benchmarks/benchmarks.proto \
+  --csharp_out=csharp/src/Google.Protobuf.Benchmarks
diff --git a/csharp/src/Google.Protobuf.Benchmarks/BenchmarkMessage1Proto3.cs b/csharp/src/Google.Protobuf.Benchmarks/BenchmarkMessage1Proto3.cs
new file mode 100644
index 0000000..c0c6d66
--- /dev/null
+++ b/csharp/src/Google.Protobuf.Benchmarks/BenchmarkMessage1Proto3.cs
@@ -0,0 +1,1980 @@
+// <auto-generated>
+//     Generated by the protocol buffer compiler.  DO NOT EDIT!
+//     source: datasets/google_message1/proto3/benchmark_message1_proto3.proto
+// </auto-generated>
+#pragma warning disable 1591, 0612, 3021
+#region Designer generated code
+
+using pb = global::Google.Protobuf;
+using pbc = global::Google.Protobuf.Collections;
+using pbr = global::Google.Protobuf.Reflection;
+using scg = global::System.Collections.Generic;
+namespace Benchmarks.Proto3 {
+
+  /// <summary>Holder for reflection information generated from datasets/google_message1/proto3/benchmark_message1_proto3.proto</summary>
+  public static partial class BenchmarkMessage1Proto3Reflection {
+
+    #region Descriptor
+    /// <summary>File descriptor for datasets/google_message1/proto3/benchmark_message1_proto3.proto</summary>
+    public static pbr::FileDescriptor Descriptor {
+      get { return descriptor; }
+    }
+    private static pbr::FileDescriptor descriptor;
+
+    static BenchmarkMessage1Proto3Reflection() {
+      byte[] descriptorData = global::System.Convert.FromBase64String(
+          string.Concat(
+            "Cj9kYXRhc2V0cy9nb29nbGVfbWVzc2FnZTEvcHJvdG8zL2JlbmNobWFya19t",
+            "ZXNzYWdlMV9wcm90bzMucHJvdG8SEWJlbmNobWFya3MucHJvdG8zIoMGCg5H",
+            "b29nbGVNZXNzYWdlMRIOCgZmaWVsZDEYASABKAkSDgoGZmllbGQ5GAkgASgJ",
+            "Eg8KB2ZpZWxkMTgYEiABKAkSDwoHZmllbGQ4MBhQIAEoCBIPCgdmaWVsZDgx",
+            "GFEgASgIEg4KBmZpZWxkMhgCIAEoBRIOCgZmaWVsZDMYAyABKAUSEQoIZmll",
+            "bGQyODAYmAIgASgFEg4KBmZpZWxkNhgGIAEoBRIPCgdmaWVsZDIyGBYgASgD",
+            "Eg4KBmZpZWxkNBgEIAEoCRIOCgZmaWVsZDUYBSADKAYSDwoHZmllbGQ1ORg7",
+            "IAEoCBIOCgZmaWVsZDcYByABKAkSDwoHZmllbGQxNhgQIAEoBRIRCghmaWVs",
+            "ZDEzMBiCASABKAUSDwoHZmllbGQxMhgMIAEoCBIPCgdmaWVsZDE3GBEgASgI",
+            "Eg8KB2ZpZWxkMTMYDSABKAgSDwoHZmllbGQxNBgOIAEoCBIQCghmaWVsZDEw",
+            "NBhoIAEoBRIQCghmaWVsZDEwMBhkIAEoBRIQCghmaWVsZDEwMRhlIAEoBRIQ",
+            "CghmaWVsZDEwMhhmIAEoCRIQCghmaWVsZDEwMxhnIAEoCRIPCgdmaWVsZDI5",
+            "GB0gASgFEg8KB2ZpZWxkMzAYHiABKAgSDwoHZmllbGQ2MBg8IAEoBRIRCghm",
+            "aWVsZDI3MRiPAiABKAUSEQoIZmllbGQyNzIYkAIgASgFEhEKCGZpZWxkMTUw",
+            "GJYBIAEoBRIPCgdmaWVsZDIzGBcgASgFEg8KB2ZpZWxkMjQYGCABKAgSDwoH",
+            "ZmllbGQyNRgZIAEoBRI8CgdmaWVsZDE1GA8gASgLMisuYmVuY2htYXJrcy5w",
+            "cm90bzMuR29vZ2xlTWVzc2FnZTFTdWJNZXNzYWdlEg8KB2ZpZWxkNzgYTiAB",
+            "KAgSDwoHZmllbGQ2NxhDIAEoBRIPCgdmaWVsZDY4GEQgASgFEhEKCGZpZWxk",
+            "MTI4GIABIAEoBRIRCghmaWVsZDEyORiBASABKAkSEQoIZmllbGQxMzEYgwEg",
+            "ASgFIvcCChhHb29nbGVNZXNzYWdlMVN1Yk1lc3NhZ2USDgoGZmllbGQxGAEg",
+            "ASgFEg4KBmZpZWxkMhgCIAEoBRIOCgZmaWVsZDMYAyABKAUSDwoHZmllbGQx",
+            "NRgPIAEoCRIPCgdmaWVsZDEyGAwgASgIEg8KB2ZpZWxkMTMYDSABKAMSDwoH",
+            "ZmllbGQxNBgOIAEoAxIPCgdmaWVsZDE2GBAgASgFEg8KB2ZpZWxkMTkYEyAB",
+            "KAUSDwoHZmllbGQyMBgUIAEoCBIPCgdmaWVsZDI4GBwgASgIEg8KB2ZpZWxk",
+            "MjEYFSABKAYSDwoHZmllbGQyMhgWIAEoBRIPCgdmaWVsZDIzGBcgASgIEhEK",
+            "CGZpZWxkMjA2GM4BIAEoCBIRCghmaWVsZDIwMxjLASABKAcSEQoIZmllbGQy",
+            "MDQYzAEgASgFEhEKCGZpZWxkMjA1GM0BIAEoCRIRCghmaWVsZDIwNxjPASAB",
+            "KAQSEQoIZmllbGQzMDAYrAIgASgEQiUKHmNvbS5nb29nbGUucHJvdG9idWYu",
+            "YmVuY2htYXJrc0gB+AEBYgZwcm90bzM="));
+      descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
+          new pbr::FileDescriptor[] { },
+          new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] {
+            new pbr::GeneratedClrTypeInfo(typeof(global::Benchmarks.Proto3.GoogleMessage1), global::Benchmarks.Proto3.GoogleMessage1.Parser, new[]{ "Field1", "Field9", "Field18", "Field80", "Field81", "Field2", "Field3", "Field280", "Field6", "Field22", "Field4", "Field5", "Field59", "Field7", "Field16", "Field130", "Field12", "Field17", "Field13", "Field14", "Field104", "Field100", "Field101", "Field102", "Field103", "Field29", "Field30", "Field60", "Field271", "Field272", "Field150", "Field23", "Field24", "Field25", "Field15", "Field78", "Field67", "Field68", "Field128", "Field129", "Field131" }, null, null, null),
+            new pbr::GeneratedClrTypeInfo(typeof(global::Benchmarks.Proto3.GoogleMessage1SubMessage), global::Benchmarks.Proto3.GoogleMessage1SubMessage.Parser, new[]{ "Field1", "Field2", "Field3", "Field15", "Field12", "Field13", "Field14", "Field16", "Field19", "Field20", "Field28", "Field21", "Field22", "Field23", "Field206", "Field203", "Field204", "Field205", "Field207", "Field300" }, null, null, null)
+          }));
+    }
+    #endregion
+
+  }
+  #region Messages
+  public sealed partial class GoogleMessage1 : pb::IMessage<GoogleMessage1> {
+    private static readonly pb::MessageParser<GoogleMessage1> _parser = new pb::MessageParser<GoogleMessage1>(() => new GoogleMessage1());
+    private pb::UnknownFieldSet _unknownFields;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public static pb::MessageParser<GoogleMessage1> Parser { get { return _parser; } }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public static pbr::MessageDescriptor Descriptor {
+      get { return global::Benchmarks.Proto3.BenchmarkMessage1Proto3Reflection.Descriptor.MessageTypes[0]; }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    pbr::MessageDescriptor pb::IMessage.Descriptor {
+      get { return Descriptor; }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public GoogleMessage1() {
+      OnConstruction();
+    }
+
+    partial void OnConstruction();
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public GoogleMessage1(GoogleMessage1 other) : this() {
+      field1_ = other.field1_;
+      field9_ = other.field9_;
+      field18_ = other.field18_;
+      field80_ = other.field80_;
+      field81_ = other.field81_;
+      field2_ = other.field2_;
+      field3_ = other.field3_;
+      field280_ = other.field280_;
+      field6_ = other.field6_;
+      field22_ = other.field22_;
+      field4_ = other.field4_;
+      field5_ = other.field5_.Clone();
+      field59_ = other.field59_;
+      field7_ = other.field7_;
+      field16_ = other.field16_;
+      field130_ = other.field130_;
+      field12_ = other.field12_;
+      field17_ = other.field17_;
+      field13_ = other.field13_;
+      field14_ = other.field14_;
+      field104_ = other.field104_;
+      field100_ = other.field100_;
+      field101_ = other.field101_;
+      field102_ = other.field102_;
+      field103_ = other.field103_;
+      field29_ = other.field29_;
+      field30_ = other.field30_;
+      field60_ = other.field60_;
+      field271_ = other.field271_;
+      field272_ = other.field272_;
+      field150_ = other.field150_;
+      field23_ = other.field23_;
+      field24_ = other.field24_;
+      field25_ = other.field25_;
+      field15_ = other.field15_ != null ? other.field15_.Clone() : null;
+      field78_ = other.field78_;
+      field67_ = other.field67_;
+      field68_ = other.field68_;
+      field128_ = other.field128_;
+      field129_ = other.field129_;
+      field131_ = other.field131_;
+      _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public GoogleMessage1 Clone() {
+      return new GoogleMessage1(this);
+    }
+
+    /// <summary>Field number for the "field1" field.</summary>
+    public const int Field1FieldNumber = 1;
+    private string field1_ = "";
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public string Field1 {
+      get { return field1_; }
+      set {
+        field1_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
+      }
+    }
+
+    /// <summary>Field number for the "field9" field.</summary>
+    public const int Field9FieldNumber = 9;
+    private string field9_ = "";
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public string Field9 {
+      get { return field9_; }
+      set {
+        field9_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
+      }
+    }
+
+    /// <summary>Field number for the "field18" field.</summary>
+    public const int Field18FieldNumber = 18;
+    private string field18_ = "";
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public string Field18 {
+      get { return field18_; }
+      set {
+        field18_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
+      }
+    }
+
+    /// <summary>Field number for the "field80" field.</summary>
+    public const int Field80FieldNumber = 80;
+    private bool field80_;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public bool Field80 {
+      get { return field80_; }
+      set {
+        field80_ = value;
+      }
+    }
+
+    /// <summary>Field number for the "field81" field.</summary>
+    public const int Field81FieldNumber = 81;
+    private bool field81_;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public bool Field81 {
+      get { return field81_; }
+      set {
+        field81_ = value;
+      }
+    }
+
+    /// <summary>Field number for the "field2" field.</summary>
+    public const int Field2FieldNumber = 2;
+    private int field2_;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public int Field2 {
+      get { return field2_; }
+      set {
+        field2_ = value;
+      }
+    }
+
+    /// <summary>Field number for the "field3" field.</summary>
+    public const int Field3FieldNumber = 3;
+    private int field3_;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public int Field3 {
+      get { return field3_; }
+      set {
+        field3_ = value;
+      }
+    }
+
+    /// <summary>Field number for the "field280" field.</summary>
+    public const int Field280FieldNumber = 280;
+    private int field280_;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public int Field280 {
+      get { return field280_; }
+      set {
+        field280_ = value;
+      }
+    }
+
+    /// <summary>Field number for the "field6" field.</summary>
+    public const int Field6FieldNumber = 6;
+    private int field6_;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public int Field6 {
+      get { return field6_; }
+      set {
+        field6_ = value;
+      }
+    }
+
+    /// <summary>Field number for the "field22" field.</summary>
+    public const int Field22FieldNumber = 22;
+    private long field22_;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public long Field22 {
+      get { return field22_; }
+      set {
+        field22_ = value;
+      }
+    }
+
+    /// <summary>Field number for the "field4" field.</summary>
+    public const int Field4FieldNumber = 4;
+    private string field4_ = "";
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public string Field4 {
+      get { return field4_; }
+      set {
+        field4_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
+      }
+    }
+
+    /// <summary>Field number for the "field5" field.</summary>
+    public const int Field5FieldNumber = 5;
+    private static readonly pb::FieldCodec<ulong> _repeated_field5_codec
+        = pb::FieldCodec.ForFixed64(42);
+    private readonly pbc::RepeatedField<ulong> field5_ = new pbc::RepeatedField<ulong>();
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public pbc::RepeatedField<ulong> Field5 {
+      get { return field5_; }
+    }
+
+    /// <summary>Field number for the "field59" field.</summary>
+    public const int Field59FieldNumber = 59;
+    private bool field59_;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public bool Field59 {
+      get { return field59_; }
+      set {
+        field59_ = value;
+      }
+    }
+
+    /// <summary>Field number for the "field7" field.</summary>
+    public const int Field7FieldNumber = 7;
+    private string field7_ = "";
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public string Field7 {
+      get { return field7_; }
+      set {
+        field7_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
+      }
+    }
+
+    /// <summary>Field number for the "field16" field.</summary>
+    public const int Field16FieldNumber = 16;
+    private int field16_;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public int Field16 {
+      get { return field16_; }
+      set {
+        field16_ = value;
+      }
+    }
+
+    /// <summary>Field number for the "field130" field.</summary>
+    public const int Field130FieldNumber = 130;
+    private int field130_;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public int Field130 {
+      get { return field130_; }
+      set {
+        field130_ = value;
+      }
+    }
+
+    /// <summary>Field number for the "field12" field.</summary>
+    public const int Field12FieldNumber = 12;
+    private bool field12_;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public bool Field12 {
+      get { return field12_; }
+      set {
+        field12_ = value;
+      }
+    }
+
+    /// <summary>Field number for the "field17" field.</summary>
+    public const int Field17FieldNumber = 17;
+    private bool field17_;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public bool Field17 {
+      get { return field17_; }
+      set {
+        field17_ = value;
+      }
+    }
+
+    /// <summary>Field number for the "field13" field.</summary>
+    public const int Field13FieldNumber = 13;
+    private bool field13_;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public bool Field13 {
+      get { return field13_; }
+      set {
+        field13_ = value;
+      }
+    }
+
+    /// <summary>Field number for the "field14" field.</summary>
+    public const int Field14FieldNumber = 14;
+    private bool field14_;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public bool Field14 {
+      get { return field14_; }
+      set {
+        field14_ = value;
+      }
+    }
+
+    /// <summary>Field number for the "field104" field.</summary>
+    public const int Field104FieldNumber = 104;
+    private int field104_;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public int Field104 {
+      get { return field104_; }
+      set {
+        field104_ = value;
+      }
+    }
+
+    /// <summary>Field number for the "field100" field.</summary>
+    public const int Field100FieldNumber = 100;
+    private int field100_;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public int Field100 {
+      get { return field100_; }
+      set {
+        field100_ = value;
+      }
+    }
+
+    /// <summary>Field number for the "field101" field.</summary>
+    public const int Field101FieldNumber = 101;
+    private int field101_;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public int Field101 {
+      get { return field101_; }
+      set {
+        field101_ = value;
+      }
+    }
+
+    /// <summary>Field number for the "field102" field.</summary>
+    public const int Field102FieldNumber = 102;
+    private string field102_ = "";
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public string Field102 {
+      get { return field102_; }
+      set {
+        field102_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
+      }
+    }
+
+    /// <summary>Field number for the "field103" field.</summary>
+    public const int Field103FieldNumber = 103;
+    private string field103_ = "";
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public string Field103 {
+      get { return field103_; }
+      set {
+        field103_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
+      }
+    }
+
+    /// <summary>Field number for the "field29" field.</summary>
+    public const int Field29FieldNumber = 29;
+    private int field29_;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public int Field29 {
+      get { return field29_; }
+      set {
+        field29_ = value;
+      }
+    }
+
+    /// <summary>Field number for the "field30" field.</summary>
+    public const int Field30FieldNumber = 30;
+    private bool field30_;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public bool Field30 {
+      get { return field30_; }
+      set {
+        field30_ = value;
+      }
+    }
+
+    /// <summary>Field number for the "field60" field.</summary>
+    public const int Field60FieldNumber = 60;
+    private int field60_;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public int Field60 {
+      get { return field60_; }
+      set {
+        field60_ = value;
+      }
+    }
+
+    /// <summary>Field number for the "field271" field.</summary>
+    public const int Field271FieldNumber = 271;
+    private int field271_;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public int Field271 {
+      get { return field271_; }
+      set {
+        field271_ = value;
+      }
+    }
+
+    /// <summary>Field number for the "field272" field.</summary>
+    public const int Field272FieldNumber = 272;
+    private int field272_;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public int Field272 {
+      get { return field272_; }
+      set {
+        field272_ = value;
+      }
+    }
+
+    /// <summary>Field number for the "field150" field.</summary>
+    public const int Field150FieldNumber = 150;
+    private int field150_;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public int Field150 {
+      get { return field150_; }
+      set {
+        field150_ = value;
+      }
+    }
+
+    /// <summary>Field number for the "field23" field.</summary>
+    public const int Field23FieldNumber = 23;
+    private int field23_;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public int Field23 {
+      get { return field23_; }
+      set {
+        field23_ = value;
+      }
+    }
+
+    /// <summary>Field number for the "field24" field.</summary>
+    public const int Field24FieldNumber = 24;
+    private bool field24_;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public bool Field24 {
+      get { return field24_; }
+      set {
+        field24_ = value;
+      }
+    }
+
+    /// <summary>Field number for the "field25" field.</summary>
+    public const int Field25FieldNumber = 25;
+    private int field25_;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public int Field25 {
+      get { return field25_; }
+      set {
+        field25_ = value;
+      }
+    }
+
+    /// <summary>Field number for the "field15" field.</summary>
+    public const int Field15FieldNumber = 15;
+    private global::Benchmarks.Proto3.GoogleMessage1SubMessage field15_;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public global::Benchmarks.Proto3.GoogleMessage1SubMessage Field15 {
+      get { return field15_; }
+      set {
+        field15_ = value;
+      }
+    }
+
+    /// <summary>Field number for the "field78" field.</summary>
+    public const int Field78FieldNumber = 78;
+    private bool field78_;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public bool Field78 {
+      get { return field78_; }
+      set {
+        field78_ = value;
+      }
+    }
+
+    /// <summary>Field number for the "field67" field.</summary>
+    public const int Field67FieldNumber = 67;
+    private int field67_;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public int Field67 {
+      get { return field67_; }
+      set {
+        field67_ = value;
+      }
+    }
+
+    /// <summary>Field number for the "field68" field.</summary>
+    public const int Field68FieldNumber = 68;
+    private int field68_;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public int Field68 {
+      get { return field68_; }
+      set {
+        field68_ = value;
+      }
+    }
+
+    /// <summary>Field number for the "field128" field.</summary>
+    public const int Field128FieldNumber = 128;
+    private int field128_;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public int Field128 {
+      get { return field128_; }
+      set {
+        field128_ = value;
+      }
+    }
+
+    /// <summary>Field number for the "field129" field.</summary>
+    public const int Field129FieldNumber = 129;
+    private string field129_ = "";
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public string Field129 {
+      get { return field129_; }
+      set {
+        field129_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
+      }
+    }
+
+    /// <summary>Field number for the "field131" field.</summary>
+    public const int Field131FieldNumber = 131;
+    private int field131_;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public int Field131 {
+      get { return field131_; }
+      set {
+        field131_ = value;
+      }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public override bool Equals(object other) {
+      return Equals(other as GoogleMessage1);
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public bool Equals(GoogleMessage1 other) {
+      if (ReferenceEquals(other, null)) {
+        return false;
+      }
+      if (ReferenceEquals(other, this)) {
+        return true;
+      }
+      if (Field1 != other.Field1) return false;
+      if (Field9 != other.Field9) return false;
+      if (Field18 != other.Field18) return false;
+      if (Field80 != other.Field80) return false;
+      if (Field81 != other.Field81) return false;
+      if (Field2 != other.Field2) return false;
+      if (Field3 != other.Field3) return false;
+      if (Field280 != other.Field280) return false;
+      if (Field6 != other.Field6) return false;
+      if (Field22 != other.Field22) return false;
+      if (Field4 != other.Field4) return false;
+      if(!field5_.Equals(other.field5_)) return false;
+      if (Field59 != other.Field59) return false;
+      if (Field7 != other.Field7) return false;
+      if (Field16 != other.Field16) return false;
+      if (Field130 != other.Field130) return false;
+      if (Field12 != other.Field12) return false;
+      if (Field17 != other.Field17) return false;
+      if (Field13 != other.Field13) return false;
+      if (Field14 != other.Field14) return false;
+      if (Field104 != other.Field104) return false;
+      if (Field100 != other.Field100) return false;
+      if (Field101 != other.Field101) return false;
+      if (Field102 != other.Field102) return false;
+      if (Field103 != other.Field103) return false;
+      if (Field29 != other.Field29) return false;
+      if (Field30 != other.Field30) return false;
+      if (Field60 != other.Field60) return false;
+      if (Field271 != other.Field271) return false;
+      if (Field272 != other.Field272) return false;
+      if (Field150 != other.Field150) return false;
+      if (Field23 != other.Field23) return false;
+      if (Field24 != other.Field24) return false;
+      if (Field25 != other.Field25) return false;
+      if (!object.Equals(Field15, other.Field15)) return false;
+      if (Field78 != other.Field78) return false;
+      if (Field67 != other.Field67) return false;
+      if (Field68 != other.Field68) return false;
+      if (Field128 != other.Field128) return false;
+      if (Field129 != other.Field129) return false;
+      if (Field131 != other.Field131) return false;
+      return Equals(_unknownFields, other._unknownFields);
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public override int GetHashCode() {
+      int hash = 1;
+      if (Field1.Length != 0) hash ^= Field1.GetHashCode();
+      if (Field9.Length != 0) hash ^= Field9.GetHashCode();
+      if (Field18.Length != 0) hash ^= Field18.GetHashCode();
+      if (Field80 != false) hash ^= Field80.GetHashCode();
+      if (Field81 != false) hash ^= Field81.GetHashCode();
+      if (Field2 != 0) hash ^= Field2.GetHashCode();
+      if (Field3 != 0) hash ^= Field3.GetHashCode();
+      if (Field280 != 0) hash ^= Field280.GetHashCode();
+      if (Field6 != 0) hash ^= Field6.GetHashCode();
+      if (Field22 != 0L) hash ^= Field22.GetHashCode();
+      if (Field4.Length != 0) hash ^= Field4.GetHashCode();
+      hash ^= field5_.GetHashCode();
+      if (Field59 != false) hash ^= Field59.GetHashCode();
+      if (Field7.Length != 0) hash ^= Field7.GetHashCode();
+      if (Field16 != 0) hash ^= Field16.GetHashCode();
+      if (Field130 != 0) hash ^= Field130.GetHashCode();
+      if (Field12 != false) hash ^= Field12.GetHashCode();
+      if (Field17 != false) hash ^= Field17.GetHashCode();
+      if (Field13 != false) hash ^= Field13.GetHashCode();
+      if (Field14 != false) hash ^= Field14.GetHashCode();
+      if (Field104 != 0) hash ^= Field104.GetHashCode();
+      if (Field100 != 0) hash ^= Field100.GetHashCode();
+      if (Field101 != 0) hash ^= Field101.GetHashCode();
+      if (Field102.Length != 0) hash ^= Field102.GetHashCode();
+      if (Field103.Length != 0) hash ^= Field103.GetHashCode();
+      if (Field29 != 0) hash ^= Field29.GetHashCode();
+      if (Field30 != false) hash ^= Field30.GetHashCode();
+      if (Field60 != 0) hash ^= Field60.GetHashCode();
+      if (Field271 != 0) hash ^= Field271.GetHashCode();
+      if (Field272 != 0) hash ^= Field272.GetHashCode();
+      if (Field150 != 0) hash ^= Field150.GetHashCode();
+      if (Field23 != 0) hash ^= Field23.GetHashCode();
+      if (Field24 != false) hash ^= Field24.GetHashCode();
+      if (Field25 != 0) hash ^= Field25.GetHashCode();
+      if (field15_ != null) hash ^= Field15.GetHashCode();
+      if (Field78 != false) hash ^= Field78.GetHashCode();
+      if (Field67 != 0) hash ^= Field67.GetHashCode();
+      if (Field68 != 0) hash ^= Field68.GetHashCode();
+      if (Field128 != 0) hash ^= Field128.GetHashCode();
+      if (Field129.Length != 0) hash ^= Field129.GetHashCode();
+      if (Field131 != 0) hash ^= Field131.GetHashCode();
+      if (_unknownFields != null) {
+        hash ^= _unknownFields.GetHashCode();
+      }
+      return hash;
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public override string ToString() {
+      return pb::JsonFormatter.ToDiagnosticString(this);
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public void WriteTo(pb::CodedOutputStream output) {
+      if (Field1.Length != 0) {
+        output.WriteRawTag(10);
+        output.WriteString(Field1);
+      }
+      if (Field2 != 0) {
+        output.WriteRawTag(16);
+        output.WriteInt32(Field2);
+      }
+      if (Field3 != 0) {
+        output.WriteRawTag(24);
+        output.WriteInt32(Field3);
+      }
+      if (Field4.Length != 0) {
+        output.WriteRawTag(34);
+        output.WriteString(Field4);
+      }
+      field5_.WriteTo(output, _repeated_field5_codec);
+      if (Field6 != 0) {
+        output.WriteRawTag(48);
+        output.WriteInt32(Field6);
+      }
+      if (Field7.Length != 0) {
+        output.WriteRawTag(58);
+        output.WriteString(Field7);
+      }
+      if (Field9.Length != 0) {
+        output.WriteRawTag(74);
+        output.WriteString(Field9);
+      }
+      if (Field12 != false) {
+        output.WriteRawTag(96);
+        output.WriteBool(Field12);
+      }
+      if (Field13 != false) {
+        output.WriteRawTag(104);
+        output.WriteBool(Field13);
+      }
+      if (Field14 != false) {
+        output.WriteRawTag(112);
+        output.WriteBool(Field14);
+      }
+      if (field15_ != null) {
+        output.WriteRawTag(122);
+        output.WriteMessage(Field15);
+      }
+      if (Field16 != 0) {
+        output.WriteRawTag(128, 1);
+        output.WriteInt32(Field16);
+      }
+      if (Field17 != false) {
+        output.WriteRawTag(136, 1);
+        output.WriteBool(Field17);
+      }
+      if (Field18.Length != 0) {
+        output.WriteRawTag(146, 1);
+        output.WriteString(Field18);
+      }
+      if (Field22 != 0L) {
+        output.WriteRawTag(176, 1);
+        output.WriteInt64(Field22);
+      }
+      if (Field23 != 0) {
+        output.WriteRawTag(184, 1);
+        output.WriteInt32(Field23);
+      }
+      if (Field24 != false) {
+        output.WriteRawTag(192, 1);
+        output.WriteBool(Field24);
+      }
+      if (Field25 != 0) {
+        output.WriteRawTag(200, 1);
+        output.WriteInt32(Field25);
+      }
+      if (Field29 != 0) {
+        output.WriteRawTag(232, 1);
+        output.WriteInt32(Field29);
+      }
+      if (Field30 != false) {
+        output.WriteRawTag(240, 1);
+        output.WriteBool(Field30);
+      }
+      if (Field59 != false) {
+        output.WriteRawTag(216, 3);
+        output.WriteBool(Field59);
+      }
+      if (Field60 != 0) {
+        output.WriteRawTag(224, 3);
+        output.WriteInt32(Field60);
+      }
+      if (Field67 != 0) {
+        output.WriteRawTag(152, 4);
+        output.WriteInt32(Field67);
+      }
+      if (Field68 != 0) {
+        output.WriteRawTag(160, 4);
+        output.WriteInt32(Field68);
+      }
+      if (Field78 != false) {
+        output.WriteRawTag(240, 4);
+        output.WriteBool(Field78);
+      }
+      if (Field80 != false) {
+        output.WriteRawTag(128, 5);
+        output.WriteBool(Field80);
+      }
+      if (Field81 != false) {
+        output.WriteRawTag(136, 5);
+        output.WriteBool(Field81);
+      }
+      if (Field100 != 0) {
+        output.WriteRawTag(160, 6);
+        output.WriteInt32(Field100);
+      }
+      if (Field101 != 0) {
+        output.WriteRawTag(168, 6);
+        output.WriteInt32(Field101);
+      }
+      if (Field102.Length != 0) {
+        output.WriteRawTag(178, 6);
+        output.WriteString(Field102);
+      }
+      if (Field103.Length != 0) {
+        output.WriteRawTag(186, 6);
+        output.WriteString(Field103);
+      }
+      if (Field104 != 0) {
+        output.WriteRawTag(192, 6);
+        output.WriteInt32(Field104);
+      }
+      if (Field128 != 0) {
+        output.WriteRawTag(128, 8);
+        output.WriteInt32(Field128);
+      }
+      if (Field129.Length != 0) {
+        output.WriteRawTag(138, 8);
+        output.WriteString(Field129);
+      }
+      if (Field130 != 0) {
+        output.WriteRawTag(144, 8);
+        output.WriteInt32(Field130);
+      }
+      if (Field131 != 0) {
+        output.WriteRawTag(152, 8);
+        output.WriteInt32(Field131);
+      }
+      if (Field150 != 0) {
+        output.WriteRawTag(176, 9);
+        output.WriteInt32(Field150);
+      }
+      if (Field271 != 0) {
+        output.WriteRawTag(248, 16);
+        output.WriteInt32(Field271);
+      }
+      if (Field272 != 0) {
+        output.WriteRawTag(128, 17);
+        output.WriteInt32(Field272);
+      }
+      if (Field280 != 0) {
+        output.WriteRawTag(192, 17);
+        output.WriteInt32(Field280);
+      }
+      if (_unknownFields != null) {
+        _unknownFields.WriteTo(output);
+      }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public int CalculateSize() {
+      int size = 0;
+      if (Field1.Length != 0) {
+        size += 1 + pb::CodedOutputStream.ComputeStringSize(Field1);
+      }
+      if (Field9.Length != 0) {
+        size += 1 + pb::CodedOutputStream.ComputeStringSize(Field9);
+      }
+      if (Field18.Length != 0) {
+        size += 2 + pb::CodedOutputStream.ComputeStringSize(Field18);
+      }
+      if (Field80 != false) {
+        size += 2 + 1;
+      }
+      if (Field81 != false) {
+        size += 2 + 1;
+      }
+      if (Field2 != 0) {
+        size += 1 + pb::CodedOutputStream.ComputeInt32Size(Field2);
+      }
+      if (Field3 != 0) {
+        size += 1 + pb::CodedOutputStream.ComputeInt32Size(Field3);
+      }
+      if (Field280 != 0) {
+        size += 2 + pb::CodedOutputStream.ComputeInt32Size(Field280);
+      }
+      if (Field6 != 0) {
+        size += 1 + pb::CodedOutputStream.ComputeInt32Size(Field6);
+      }
+      if (Field22 != 0L) {
+        size += 2 + pb::CodedOutputStream.ComputeInt64Size(Field22);
+      }
+      if (Field4.Length != 0) {
+        size += 1 + pb::CodedOutputStream.ComputeStringSize(Field4);
+      }
+      size += field5_.CalculateSize(_repeated_field5_codec);
+      if (Field59 != false) {
+        size += 2 + 1;
+      }
+      if (Field7.Length != 0) {
+        size += 1 + pb::CodedOutputStream.ComputeStringSize(Field7);
+      }
+      if (Field16 != 0) {
+        size += 2 + pb::CodedOutputStream.ComputeInt32Size(Field16);
+      }
+      if (Field130 != 0) {
+        size += 2 + pb::CodedOutputStream.ComputeInt32Size(Field130);
+      }
+      if (Field12 != false) {
+        size += 1 + 1;
+      }
+      if (Field17 != false) {
+        size += 2 + 1;
+      }
+      if (Field13 != false) {
+        size += 1 + 1;
+      }
+      if (Field14 != false) {
+        size += 1 + 1;
+      }
+      if (Field104 != 0) {
+        size += 2 + pb::CodedOutputStream.ComputeInt32Size(Field104);
+      }
+      if (Field100 != 0) {
+        size += 2 + pb::CodedOutputStream.ComputeInt32Size(Field100);
+      }
+      if (Field101 != 0) {
+        size += 2 + pb::CodedOutputStream.ComputeInt32Size(Field101);
+      }
+      if (Field102.Length != 0) {
+        size += 2 + pb::CodedOutputStream.ComputeStringSize(Field102);
+      }
+      if (Field103.Length != 0) {
+        size += 2 + pb::CodedOutputStream.ComputeStringSize(Field103);
+      }
+      if (Field29 != 0) {
+        size += 2 + pb::CodedOutputStream.ComputeInt32Size(Field29);
+      }
+      if (Field30 != false) {
+        size += 2 + 1;
+      }
+      if (Field60 != 0) {
+        size += 2 + pb::CodedOutputStream.ComputeInt32Size(Field60);
+      }
+      if (Field271 != 0) {
+        size += 2 + pb::CodedOutputStream.ComputeInt32Size(Field271);
+      }
+      if (Field272 != 0) {
+        size += 2 + pb::CodedOutputStream.ComputeInt32Size(Field272);
+      }
+      if (Field150 != 0) {
+        size += 2 + pb::CodedOutputStream.ComputeInt32Size(Field150);
+      }
+      if (Field23 != 0) {
+        size += 2 + pb::CodedOutputStream.ComputeInt32Size(Field23);
+      }
+      if (Field24 != false) {
+        size += 2 + 1;
+      }
+      if (Field25 != 0) {
+        size += 2 + pb::CodedOutputStream.ComputeInt32Size(Field25);
+      }
+      if (field15_ != null) {
+        size += 1 + pb::CodedOutputStream.ComputeMessageSize(Field15);
+      }
+      if (Field78 != false) {
+        size += 2 + 1;
+      }
+      if (Field67 != 0) {
+        size += 2 + pb::CodedOutputStream.ComputeInt32Size(Field67);
+      }
+      if (Field68 != 0) {
+        size += 2 + pb::CodedOutputStream.ComputeInt32Size(Field68);
+      }
+      if (Field128 != 0) {
+        size += 2 + pb::CodedOutputStream.ComputeInt32Size(Field128);
+      }
+      if (Field129.Length != 0) {
+        size += 2 + pb::CodedOutputStream.ComputeStringSize(Field129);
+      }
+      if (Field131 != 0) {
+        size += 2 + pb::CodedOutputStream.ComputeInt32Size(Field131);
+      }
+      if (_unknownFields != null) {
+        size += _unknownFields.CalculateSize();
+      }
+      return size;
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public void MergeFrom(GoogleMessage1 other) {
+      if (other == null) {
+        return;
+      }
+      if (other.Field1.Length != 0) {
+        Field1 = other.Field1;
+      }
+      if (other.Field9.Length != 0) {
+        Field9 = other.Field9;
+      }
+      if (other.Field18.Length != 0) {
+        Field18 = other.Field18;
+      }
+      if (other.Field80 != false) {
+        Field80 = other.Field80;
+      }
+      if (other.Field81 != false) {
+        Field81 = other.Field81;
+      }
+      if (other.Field2 != 0) {
+        Field2 = other.Field2;
+      }
+      if (other.Field3 != 0) {
+        Field3 = other.Field3;
+      }
+      if (other.Field280 != 0) {
+        Field280 = other.Field280;
+      }
+      if (other.Field6 != 0) {
+        Field6 = other.Field6;
+      }
+      if (other.Field22 != 0L) {
+        Field22 = other.Field22;
+      }
+      if (other.Field4.Length != 0) {
+        Field4 = other.Field4;
+      }
+      field5_.Add(other.field5_);
+      if (other.Field59 != false) {
+        Field59 = other.Field59;
+      }
+      if (other.Field7.Length != 0) {
+        Field7 = other.Field7;
+      }
+      if (other.Field16 != 0) {
+        Field16 = other.Field16;
+      }
+      if (other.Field130 != 0) {
+        Field130 = other.Field130;
+      }
+      if (other.Field12 != false) {
+        Field12 = other.Field12;
+      }
+      if (other.Field17 != false) {
+        Field17 = other.Field17;
+      }
+      if (other.Field13 != false) {
+        Field13 = other.Field13;
+      }
+      if (other.Field14 != false) {
+        Field14 = other.Field14;
+      }
+      if (other.Field104 != 0) {
+        Field104 = other.Field104;
+      }
+      if (other.Field100 != 0) {
+        Field100 = other.Field100;
+      }
+      if (other.Field101 != 0) {
+        Field101 = other.Field101;
+      }
+      if (other.Field102.Length != 0) {
+        Field102 = other.Field102;
+      }
+      if (other.Field103.Length != 0) {
+        Field103 = other.Field103;
+      }
+      if (other.Field29 != 0) {
+        Field29 = other.Field29;
+      }
+      if (other.Field30 != false) {
+        Field30 = other.Field30;
+      }
+      if (other.Field60 != 0) {
+        Field60 = other.Field60;
+      }
+      if (other.Field271 != 0) {
+        Field271 = other.Field271;
+      }
+      if (other.Field272 != 0) {
+        Field272 = other.Field272;
+      }
+      if (other.Field150 != 0) {
+        Field150 = other.Field150;
+      }
+      if (other.Field23 != 0) {
+        Field23 = other.Field23;
+      }
+      if (other.Field24 != false) {
+        Field24 = other.Field24;
+      }
+      if (other.Field25 != 0) {
+        Field25 = other.Field25;
+      }
+      if (other.field15_ != null) {
+        if (field15_ == null) {
+          Field15 = new global::Benchmarks.Proto3.GoogleMessage1SubMessage();
+        }
+        Field15.MergeFrom(other.Field15);
+      }
+      if (other.Field78 != false) {
+        Field78 = other.Field78;
+      }
+      if (other.Field67 != 0) {
+        Field67 = other.Field67;
+      }
+      if (other.Field68 != 0) {
+        Field68 = other.Field68;
+      }
+      if (other.Field128 != 0) {
+        Field128 = other.Field128;
+      }
+      if (other.Field129.Length != 0) {
+        Field129 = other.Field129;
+      }
+      if (other.Field131 != 0) {
+        Field131 = other.Field131;
+      }
+      _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public void MergeFrom(pb::CodedInputStream input) {
+      uint tag;
+      while ((tag = input.ReadTag()) != 0) {
+        switch(tag) {
+          default:
+            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
+            break;
+          case 10: {
+            Field1 = input.ReadString();
+            break;
+          }
+          case 16: {
+            Field2 = input.ReadInt32();
+            break;
+          }
+          case 24: {
+            Field3 = input.ReadInt32();
+            break;
+          }
+          case 34: {
+            Field4 = input.ReadString();
+            break;
+          }
+          case 42:
+          case 41: {
+            field5_.AddEntriesFrom(input, _repeated_field5_codec);
+            break;
+          }
+          case 48: {
+            Field6 = input.ReadInt32();
+            break;
+          }
+          case 58: {
+            Field7 = input.ReadString();
+            break;
+          }
+          case 74: {
+            Field9 = input.ReadString();
+            break;
+          }
+          case 96: {
+            Field12 = input.ReadBool();
+            break;
+          }
+          case 104: {
+            Field13 = input.ReadBool();
+            break;
+          }
+          case 112: {
+            Field14 = input.ReadBool();
+            break;
+          }
+          case 122: {
+            if (field15_ == null) {
+              Field15 = new global::Benchmarks.Proto3.GoogleMessage1SubMessage();
+            }
+            input.ReadMessage(Field15);
+            break;
+          }
+          case 128: {
+            Field16 = input.ReadInt32();
+            break;
+          }
+          case 136: {
+            Field17 = input.ReadBool();
+            break;
+          }
+          case 146: {
+            Field18 = input.ReadString();
+            break;
+          }
+          case 176: {
+            Field22 = input.ReadInt64();
+            break;
+          }
+          case 184: {
+            Field23 = input.ReadInt32();
+            break;
+          }
+          case 192: {
+            Field24 = input.ReadBool();
+            break;
+          }
+          case 200: {
+            Field25 = input.ReadInt32();
+            break;
+          }
+          case 232: {
+            Field29 = input.ReadInt32();
+            break;
+          }
+          case 240: {
+            Field30 = input.ReadBool();
+            break;
+          }
+          case 472: {
+            Field59 = input.ReadBool();
+            break;
+          }
+          case 480: {
+            Field60 = input.ReadInt32();
+            break;
+          }
+          case 536: {
+            Field67 = input.ReadInt32();
+            break;
+          }
+          case 544: {
+            Field68 = input.ReadInt32();
+            break;
+          }
+          case 624: {
+            Field78 = input.ReadBool();
+            break;
+          }
+          case 640: {
+            Field80 = input.ReadBool();
+            break;
+          }
+          case 648: {
+            Field81 = input.ReadBool();
+            break;
+          }
+          case 800: {
+            Field100 = input.ReadInt32();
+            break;
+          }
+          case 808: {
+            Field101 = input.ReadInt32();
+            break;
+          }
+          case 818: {
+            Field102 = input.ReadString();
+            break;
+          }
+          case 826: {
+            Field103 = input.ReadString();
+            break;
+          }
+          case 832: {
+            Field104 = input.ReadInt32();
+            break;
+          }
+          case 1024: {
+            Field128 = input.ReadInt32();
+            break;
+          }
+          case 1034: {
+            Field129 = input.ReadString();
+            break;
+          }
+          case 1040: {
+            Field130 = input.ReadInt32();
+            break;
+          }
+          case 1048: {
+            Field131 = input.ReadInt32();
+            break;
+          }
+          case 1200: {
+            Field150 = input.ReadInt32();
+            break;
+          }
+          case 2168: {
+            Field271 = input.ReadInt32();
+            break;
+          }
+          case 2176: {
+            Field272 = input.ReadInt32();
+            break;
+          }
+          case 2240: {
+            Field280 = input.ReadInt32();
+            break;
+          }
+        }
+      }
+    }
+
+  }
+
+  public sealed partial class GoogleMessage1SubMessage : pb::IMessage<GoogleMessage1SubMessage> {
+    private static readonly pb::MessageParser<GoogleMessage1SubMessage> _parser = new pb::MessageParser<GoogleMessage1SubMessage>(() => new GoogleMessage1SubMessage());
+    private pb::UnknownFieldSet _unknownFields;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public static pb::MessageParser<GoogleMessage1SubMessage> Parser { get { return _parser; } }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public static pbr::MessageDescriptor Descriptor {
+      get { return global::Benchmarks.Proto3.BenchmarkMessage1Proto3Reflection.Descriptor.MessageTypes[1]; }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    pbr::MessageDescriptor pb::IMessage.Descriptor {
+      get { return Descriptor; }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public GoogleMessage1SubMessage() {
+      OnConstruction();
+    }
+
+    partial void OnConstruction();
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public GoogleMessage1SubMessage(GoogleMessage1SubMessage other) : this() {
+      field1_ = other.field1_;
+      field2_ = other.field2_;
+      field3_ = other.field3_;
+      field15_ = other.field15_;
+      field12_ = other.field12_;
+      field13_ = other.field13_;
+      field14_ = other.field14_;
+      field16_ = other.field16_;
+      field19_ = other.field19_;
+      field20_ = other.field20_;
+      field28_ = other.field28_;
+      field21_ = other.field21_;
+      field22_ = other.field22_;
+      field23_ = other.field23_;
+      field206_ = other.field206_;
+      field203_ = other.field203_;
+      field204_ = other.field204_;
+      field205_ = other.field205_;
+      field207_ = other.field207_;
+      field300_ = other.field300_;
+      _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public GoogleMessage1SubMessage Clone() {
+      return new GoogleMessage1SubMessage(this);
+    }
+
+    /// <summary>Field number for the "field1" field.</summary>
+    public const int Field1FieldNumber = 1;
+    private int field1_;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public int Field1 {
+      get { return field1_; }
+      set {
+        field1_ = value;
+      }
+    }
+
+    /// <summary>Field number for the "field2" field.</summary>
+    public const int Field2FieldNumber = 2;
+    private int field2_;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public int Field2 {
+      get { return field2_; }
+      set {
+        field2_ = value;
+      }
+    }
+
+    /// <summary>Field number for the "field3" field.</summary>
+    public const int Field3FieldNumber = 3;
+    private int field3_;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public int Field3 {
+      get { return field3_; }
+      set {
+        field3_ = value;
+      }
+    }
+
+    /// <summary>Field number for the "field15" field.</summary>
+    public const int Field15FieldNumber = 15;
+    private string field15_ = "";
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public string Field15 {
+      get { return field15_; }
+      set {
+        field15_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
+      }
+    }
+
+    /// <summary>Field number for the "field12" field.</summary>
+    public const int Field12FieldNumber = 12;
+    private bool field12_;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public bool Field12 {
+      get { return field12_; }
+      set {
+        field12_ = value;
+      }
+    }
+
+    /// <summary>Field number for the "field13" field.</summary>
+    public const int Field13FieldNumber = 13;
+    private long field13_;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public long Field13 {
+      get { return field13_; }
+      set {
+        field13_ = value;
+      }
+    }
+
+    /// <summary>Field number for the "field14" field.</summary>
+    public const int Field14FieldNumber = 14;
+    private long field14_;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public long Field14 {
+      get { return field14_; }
+      set {
+        field14_ = value;
+      }
+    }
+
+    /// <summary>Field number for the "field16" field.</summary>
+    public const int Field16FieldNumber = 16;
+    private int field16_;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public int Field16 {
+      get { return field16_; }
+      set {
+        field16_ = value;
+      }
+    }
+
+    /// <summary>Field number for the "field19" field.</summary>
+    public const int Field19FieldNumber = 19;
+    private int field19_;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public int Field19 {
+      get { return field19_; }
+      set {
+        field19_ = value;
+      }
+    }
+
+    /// <summary>Field number for the "field20" field.</summary>
+    public const int Field20FieldNumber = 20;
+    private bool field20_;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public bool Field20 {
+      get { return field20_; }
+      set {
+        field20_ = value;
+      }
+    }
+
+    /// <summary>Field number for the "field28" field.</summary>
+    public const int Field28FieldNumber = 28;
+    private bool field28_;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public bool Field28 {
+      get { return field28_; }
+      set {
+        field28_ = value;
+      }
+    }
+
+    /// <summary>Field number for the "field21" field.</summary>
+    public const int Field21FieldNumber = 21;
+    private ulong field21_;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public ulong Field21 {
+      get { return field21_; }
+      set {
+        field21_ = value;
+      }
+    }
+
+    /// <summary>Field number for the "field22" field.</summary>
+    public const int Field22FieldNumber = 22;
+    private int field22_;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public int Field22 {
+      get { return field22_; }
+      set {
+        field22_ = value;
+      }
+    }
+
+    /// <summary>Field number for the "field23" field.</summary>
+    public const int Field23FieldNumber = 23;
+    private bool field23_;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public bool Field23 {
+      get { return field23_; }
+      set {
+        field23_ = value;
+      }
+    }
+
+    /// <summary>Field number for the "field206" field.</summary>
+    public const int Field206FieldNumber = 206;
+    private bool field206_;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public bool Field206 {
+      get { return field206_; }
+      set {
+        field206_ = value;
+      }
+    }
+
+    /// <summary>Field number for the "field203" field.</summary>
+    public const int Field203FieldNumber = 203;
+    private uint field203_;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public uint Field203 {
+      get { return field203_; }
+      set {
+        field203_ = value;
+      }
+    }
+
+    /// <summary>Field number for the "field204" field.</summary>
+    public const int Field204FieldNumber = 204;
+    private int field204_;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public int Field204 {
+      get { return field204_; }
+      set {
+        field204_ = value;
+      }
+    }
+
+    /// <summary>Field number for the "field205" field.</summary>
+    public const int Field205FieldNumber = 205;
+    private string field205_ = "";
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public string Field205 {
+      get { return field205_; }
+      set {
+        field205_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
+      }
+    }
+
+    /// <summary>Field number for the "field207" field.</summary>
+    public const int Field207FieldNumber = 207;
+    private ulong field207_;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public ulong Field207 {
+      get { return field207_; }
+      set {
+        field207_ = value;
+      }
+    }
+
+    /// <summary>Field number for the "field300" field.</summary>
+    public const int Field300FieldNumber = 300;
+    private ulong field300_;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public ulong Field300 {
+      get { return field300_; }
+      set {
+        field300_ = value;
+      }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public override bool Equals(object other) {
+      return Equals(other as GoogleMessage1SubMessage);
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public bool Equals(GoogleMessage1SubMessage other) {
+      if (ReferenceEquals(other, null)) {
+        return false;
+      }
+      if (ReferenceEquals(other, this)) {
+        return true;
+      }
+      if (Field1 != other.Field1) return false;
+      if (Field2 != other.Field2) return false;
+      if (Field3 != other.Field3) return false;
+      if (Field15 != other.Field15) return false;
+      if (Field12 != other.Field12) return false;
+      if (Field13 != other.Field13) return false;
+      if (Field14 != other.Field14) return false;
+      if (Field16 != other.Field16) return false;
+      if (Field19 != other.Field19) return false;
+      if (Field20 != other.Field20) return false;
+      if (Field28 != other.Field28) return false;
+      if (Field21 != other.Field21) return false;
+      if (Field22 != other.Field22) return false;
+      if (Field23 != other.Field23) return false;
+      if (Field206 != other.Field206) return false;
+      if (Field203 != other.Field203) return false;
+      if (Field204 != other.Field204) return false;
+      if (Field205 != other.Field205) return false;
+      if (Field207 != other.Field207) return false;
+      if (Field300 != other.Field300) return false;
+      return Equals(_unknownFields, other._unknownFields);
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public override int GetHashCode() {
+      int hash = 1;
+      if (Field1 != 0) hash ^= Field1.GetHashCode();
+      if (Field2 != 0) hash ^= Field2.GetHashCode();
+      if (Field3 != 0) hash ^= Field3.GetHashCode();
+      if (Field15.Length != 0) hash ^= Field15.GetHashCode();
+      if (Field12 != false) hash ^= Field12.GetHashCode();
+      if (Field13 != 0L) hash ^= Field13.GetHashCode();
+      if (Field14 != 0L) hash ^= Field14.GetHashCode();
+      if (Field16 != 0) hash ^= Field16.GetHashCode();
+      if (Field19 != 0) hash ^= Field19.GetHashCode();
+      if (Field20 != false) hash ^= Field20.GetHashCode();
+      if (Field28 != false) hash ^= Field28.GetHashCode();
+      if (Field21 != 0UL) hash ^= Field21.GetHashCode();
+      if (Field22 != 0) hash ^= Field22.GetHashCode();
+      if (Field23 != false) hash ^= Field23.GetHashCode();
+      if (Field206 != false) hash ^= Field206.GetHashCode();
+      if (Field203 != 0) hash ^= Field203.GetHashCode();
+      if (Field204 != 0) hash ^= Field204.GetHashCode();
+      if (Field205.Length != 0) hash ^= Field205.GetHashCode();
+      if (Field207 != 0UL) hash ^= Field207.GetHashCode();
+      if (Field300 != 0UL) hash ^= Field300.GetHashCode();
+      if (_unknownFields != null) {
+        hash ^= _unknownFields.GetHashCode();
+      }
+      return hash;
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public override string ToString() {
+      return pb::JsonFormatter.ToDiagnosticString(this);
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public void WriteTo(pb::CodedOutputStream output) {
+      if (Field1 != 0) {
+        output.WriteRawTag(8);
+        output.WriteInt32(Field1);
+      }
+      if (Field2 != 0) {
+        output.WriteRawTag(16);
+        output.WriteInt32(Field2);
+      }
+      if (Field3 != 0) {
+        output.WriteRawTag(24);
+        output.WriteInt32(Field3);
+      }
+      if (Field12 != false) {
+        output.WriteRawTag(96);
+        output.WriteBool(Field12);
+      }
+      if (Field13 != 0L) {
+        output.WriteRawTag(104);
+        output.WriteInt64(Field13);
+      }
+      if (Field14 != 0L) {
+        output.WriteRawTag(112);
+        output.WriteInt64(Field14);
+      }
+      if (Field15.Length != 0) {
+        output.WriteRawTag(122);
+        output.WriteString(Field15);
+      }
+      if (Field16 != 0) {
+        output.WriteRawTag(128, 1);
+        output.WriteInt32(Field16);
+      }
+      if (Field19 != 0) {
+        output.WriteRawTag(152, 1);
+        output.WriteInt32(Field19);
+      }
+      if (Field20 != false) {
+        output.WriteRawTag(160, 1);
+        output.WriteBool(Field20);
+      }
+      if (Field21 != 0UL) {
+        output.WriteRawTag(169, 1);
+        output.WriteFixed64(Field21);
+      }
+      if (Field22 != 0) {
+        output.WriteRawTag(176, 1);
+        output.WriteInt32(Field22);
+      }
+      if (Field23 != false) {
+        output.WriteRawTag(184, 1);
+        output.WriteBool(Field23);
+      }
+      if (Field28 != false) {
+        output.WriteRawTag(224, 1);
+        output.WriteBool(Field28);
+      }
+      if (Field203 != 0) {
+        output.WriteRawTag(221, 12);
+        output.WriteFixed32(Field203);
+      }
+      if (Field204 != 0) {
+        output.WriteRawTag(224, 12);
+        output.WriteInt32(Field204);
+      }
+      if (Field205.Length != 0) {
+        output.WriteRawTag(234, 12);
+        output.WriteString(Field205);
+      }
+      if (Field206 != false) {
+        output.WriteRawTag(240, 12);
+        output.WriteBool(Field206);
+      }
+      if (Field207 != 0UL) {
+        output.WriteRawTag(248, 12);
+        output.WriteUInt64(Field207);
+      }
+      if (Field300 != 0UL) {
+        output.WriteRawTag(224, 18);
+        output.WriteUInt64(Field300);
+      }
+      if (_unknownFields != null) {
+        _unknownFields.WriteTo(output);
+      }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public int CalculateSize() {
+      int size = 0;
+      if (Field1 != 0) {
+        size += 1 + pb::CodedOutputStream.ComputeInt32Size(Field1);
+      }
+      if (Field2 != 0) {
+        size += 1 + pb::CodedOutputStream.ComputeInt32Size(Field2);
+      }
+      if (Field3 != 0) {
+        size += 1 + pb::CodedOutputStream.ComputeInt32Size(Field3);
+      }
+      if (Field15.Length != 0) {
+        size += 1 + pb::CodedOutputStream.ComputeStringSize(Field15);
+      }
+      if (Field12 != false) {
+        size += 1 + 1;
+      }
+      if (Field13 != 0L) {
+        size += 1 + pb::CodedOutputStream.ComputeInt64Size(Field13);
+      }
+      if (Field14 != 0L) {
+        size += 1 + pb::CodedOutputStream.ComputeInt64Size(Field14);
+      }
+      if (Field16 != 0) {
+        size += 2 + pb::CodedOutputStream.ComputeInt32Size(Field16);
+      }
+      if (Field19 != 0) {
+        size += 2 + pb::CodedOutputStream.ComputeInt32Size(Field19);
+      }
+      if (Field20 != false) {
+        size += 2 + 1;
+      }
+      if (Field28 != false) {
+        size += 2 + 1;
+      }
+      if (Field21 != 0UL) {
+        size += 2 + 8;
+      }
+      if (Field22 != 0) {
+        size += 2 + pb::CodedOutputStream.ComputeInt32Size(Field22);
+      }
+      if (Field23 != false) {
+        size += 2 + 1;
+      }
+      if (Field206 != false) {
+        size += 2 + 1;
+      }
+      if (Field203 != 0) {
+        size += 2 + 4;
+      }
+      if (Field204 != 0) {
+        size += 2 + pb::CodedOutputStream.ComputeInt32Size(Field204);
+      }
+      if (Field205.Length != 0) {
+        size += 2 + pb::CodedOutputStream.ComputeStringSize(Field205);
+      }
+      if (Field207 != 0UL) {
+        size += 2 + pb::CodedOutputStream.ComputeUInt64Size(Field207);
+      }
+      if (Field300 != 0UL) {
+        size += 2 + pb::CodedOutputStream.ComputeUInt64Size(Field300);
+      }
+      if (_unknownFields != null) {
+        size += _unknownFields.CalculateSize();
+      }
+      return size;
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public void MergeFrom(GoogleMessage1SubMessage other) {
+      if (other == null) {
+        return;
+      }
+      if (other.Field1 != 0) {
+        Field1 = other.Field1;
+      }
+      if (other.Field2 != 0) {
+        Field2 = other.Field2;
+      }
+      if (other.Field3 != 0) {
+        Field3 = other.Field3;
+      }
+      if (other.Field15.Length != 0) {
+        Field15 = other.Field15;
+      }
+      if (other.Field12 != false) {
+        Field12 = other.Field12;
+      }
+      if (other.Field13 != 0L) {
+        Field13 = other.Field13;
+      }
+      if (other.Field14 != 0L) {
+        Field14 = other.Field14;
+      }
+      if (other.Field16 != 0) {
+        Field16 = other.Field16;
+      }
+      if (other.Field19 != 0) {
+        Field19 = other.Field19;
+      }
+      if (other.Field20 != false) {
+        Field20 = other.Field20;
+      }
+      if (other.Field28 != false) {
+        Field28 = other.Field28;
+      }
+      if (other.Field21 != 0UL) {
+        Field21 = other.Field21;
+      }
+      if (other.Field22 != 0) {
+        Field22 = other.Field22;
+      }
+      if (other.Field23 != false) {
+        Field23 = other.Field23;
+      }
+      if (other.Field206 != false) {
+        Field206 = other.Field206;
+      }
+      if (other.Field203 != 0) {
+        Field203 = other.Field203;
+      }
+      if (other.Field204 != 0) {
+        Field204 = other.Field204;
+      }
+      if (other.Field205.Length != 0) {
+        Field205 = other.Field205;
+      }
+      if (other.Field207 != 0UL) {
+        Field207 = other.Field207;
+      }
+      if (other.Field300 != 0UL) {
+        Field300 = other.Field300;
+      }
+      _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public void MergeFrom(pb::CodedInputStream input) {
+      uint tag;
+      while ((tag = input.ReadTag()) != 0) {
+        switch(tag) {
+          default:
+            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
+            break;
+          case 8: {
+            Field1 = input.ReadInt32();
+            break;
+          }
+          case 16: {
+            Field2 = input.ReadInt32();
+            break;
+          }
+          case 24: {
+            Field3 = input.ReadInt32();
+            break;
+          }
+          case 96: {
+            Field12 = input.ReadBool();
+            break;
+          }
+          case 104: {
+            Field13 = input.ReadInt64();
+            break;
+          }
+          case 112: {
+            Field14 = input.ReadInt64();
+            break;
+          }
+          case 122: {
+            Field15 = input.ReadString();
+            break;
+          }
+          case 128: {
+            Field16 = input.ReadInt32();
+            break;
+          }
+          case 152: {
+            Field19 = input.ReadInt32();
+            break;
+          }
+          case 160: {
+            Field20 = input.ReadBool();
+            break;
+          }
+          case 169: {
+            Field21 = input.ReadFixed64();
+            break;
+          }
+          case 176: {
+            Field22 = input.ReadInt32();
+            break;
+          }
+          case 184: {
+            Field23 = input.ReadBool();
+            break;
+          }
+          case 224: {
+            Field28 = input.ReadBool();
+            break;
+          }
+          case 1629: {
+            Field203 = input.ReadFixed32();
+            break;
+          }
+          case 1632: {
+            Field204 = input.ReadInt32();
+            break;
+          }
+          case 1642: {
+            Field205 = input.ReadString();
+            break;
+          }
+          case 1648: {
+            Field206 = input.ReadBool();
+            break;
+          }
+          case 1656: {
+            Field207 = input.ReadUInt64();
+            break;
+          }
+          case 2400: {
+            Field300 = input.ReadUInt64();
+            break;
+          }
+        }
+      }
+    }
+
+  }
+
+  #endregion
+
+}
+
+#endregion Designer generated code
diff --git a/csharp/src/Google.Protobuf.Benchmarks/Benchmarks.cs b/csharp/src/Google.Protobuf.Benchmarks/Benchmarks.cs
new file mode 100644
index 0000000..d2af7ee
--- /dev/null
+++ b/csharp/src/Google.Protobuf.Benchmarks/Benchmarks.cs
@@ -0,0 +1,250 @@
+// <auto-generated>
+//     Generated by the protocol buffer compiler.  DO NOT EDIT!
+//     source: benchmarks.proto
+// </auto-generated>
+#pragma warning disable 1591, 0612, 3021
+#region Designer generated code
+
+using pb = global::Google.Protobuf;
+using pbc = global::Google.Protobuf.Collections;
+using pbr = global::Google.Protobuf.Reflection;
+using scg = global::System.Collections.Generic;
+namespace Benchmarks {
+
+  /// <summary>Holder for reflection information generated from benchmarks.proto</summary>
+  public static partial class BenchmarksReflection {
+
+    #region Descriptor
+    /// <summary>File descriptor for benchmarks.proto</summary>
+    public static pbr::FileDescriptor Descriptor {
+      get { return descriptor; }
+    }
+    private static pbr::FileDescriptor descriptor;
+
+    static BenchmarksReflection() {
+      byte[] descriptorData = global::System.Convert.FromBase64String(
+          string.Concat(
+            "ChBiZW5jaG1hcmtzLnByb3RvEgpiZW5jaG1hcmtzIkcKEEJlbmNobWFya0Rh",
+            "dGFzZXQSDAoEbmFtZRgBIAEoCRIUCgxtZXNzYWdlX25hbWUYAiABKAkSDwoH",
+            "cGF5bG9hZBgDIAMoDEIgCh5jb20uZ29vZ2xlLnByb3RvYnVmLmJlbmNobWFy",
+            "a3NiBnByb3RvMw=="));
+      descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
+          new pbr::FileDescriptor[] { },
+          new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] {
+            new pbr::GeneratedClrTypeInfo(typeof(global::Benchmarks.BenchmarkDataset), global::Benchmarks.BenchmarkDataset.Parser, new[]{ "Name", "MessageName", "Payload" }, null, null, null)
+          }));
+    }
+    #endregion
+
+  }
+  #region Messages
+  public sealed partial class BenchmarkDataset : pb::IMessage<BenchmarkDataset> {
+    private static readonly pb::MessageParser<BenchmarkDataset> _parser = new pb::MessageParser<BenchmarkDataset>(() => new BenchmarkDataset());
+    private pb::UnknownFieldSet _unknownFields;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public static pb::MessageParser<BenchmarkDataset> Parser { get { return _parser; } }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public static pbr::MessageDescriptor Descriptor {
+      get { return global::Benchmarks.BenchmarksReflection.Descriptor.MessageTypes[0]; }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    pbr::MessageDescriptor pb::IMessage.Descriptor {
+      get { return Descriptor; }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public BenchmarkDataset() {
+      OnConstruction();
+    }
+
+    partial void OnConstruction();
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public BenchmarkDataset(BenchmarkDataset other) : this() {
+      name_ = other.name_;
+      messageName_ = other.messageName_;
+      payload_ = other.payload_.Clone();
+      _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public BenchmarkDataset Clone() {
+      return new BenchmarkDataset(this);
+    }
+
+    /// <summary>Field number for the "name" field.</summary>
+    public const int NameFieldNumber = 1;
+    private string name_ = "";
+    /// <summary>
+    /// Name of the benchmark dataset.  This should be unique across all datasets.
+    /// Should only contain word characters: [a-zA-Z0-9_]
+    /// </summary>
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public string Name {
+      get { return name_; }
+      set {
+        name_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
+      }
+    }
+
+    /// <summary>Field number for the "message_name" field.</summary>
+    public const int MessageNameFieldNumber = 2;
+    private string messageName_ = "";
+    /// <summary>
+    /// Fully-qualified name of the protobuf message for this dataset.
+    /// It will be one of the messages defined benchmark_messages_proto2.proto
+    /// or benchmark_messages_proto3.proto.
+    ///
+    /// Implementations that do not support reflection can implement this with
+    /// an explicit "if/else" chain that lists every known message defined
+    /// in those files.
+    /// </summary>
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public string MessageName {
+      get { return messageName_; }
+      set {
+        messageName_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
+      }
+    }
+
+    /// <summary>Field number for the "payload" field.</summary>
+    public const int PayloadFieldNumber = 3;
+    private static readonly pb::FieldCodec<pb::ByteString> _repeated_payload_codec
+        = pb::FieldCodec.ForBytes(26);
+    private readonly pbc::RepeatedField<pb::ByteString> payload_ = new pbc::RepeatedField<pb::ByteString>();
+    /// <summary>
+    /// The payload(s) for this dataset.  They should be parsed or serialized
+    /// in sequence, in a loop, ie.
+    ///
+    ///  while (!benchmarkDone) {  // Benchmark runner decides when to exit.
+    ///    for (i = 0; i &lt; benchmark.payload.length; i++) {
+    ///      parse(benchmark.payload[i])
+    ///    }
+    ///  }
+    ///
+    /// This is intended to let datasets include a variety of data to provide
+    /// potentially more realistic results than just parsing the same message
+    /// over and over.  A single message parsed repeatedly could yield unusually
+    /// good branch prediction performance.
+    /// </summary>
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public pbc::RepeatedField<pb::ByteString> Payload {
+      get { return payload_; }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public override bool Equals(object other) {
+      return Equals(other as BenchmarkDataset);
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public bool Equals(BenchmarkDataset other) {
+      if (ReferenceEquals(other, null)) {
+        return false;
+      }
+      if (ReferenceEquals(other, this)) {
+        return true;
+      }
+      if (Name != other.Name) return false;
+      if (MessageName != other.MessageName) return false;
+      if(!payload_.Equals(other.payload_)) return false;
+      return Equals(_unknownFields, other._unknownFields);
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public override int GetHashCode() {
+      int hash = 1;
+      if (Name.Length != 0) hash ^= Name.GetHashCode();
+      if (MessageName.Length != 0) hash ^= MessageName.GetHashCode();
+      hash ^= payload_.GetHashCode();
+      if (_unknownFields != null) {
+        hash ^= _unknownFields.GetHashCode();
+      }
+      return hash;
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public override string ToString() {
+      return pb::JsonFormatter.ToDiagnosticString(this);
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public void WriteTo(pb::CodedOutputStream output) {
+      if (Name.Length != 0) {
+        output.WriteRawTag(10);
+        output.WriteString(Name);
+      }
+      if (MessageName.Length != 0) {
+        output.WriteRawTag(18);
+        output.WriteString(MessageName);
+      }
+      payload_.WriteTo(output, _repeated_payload_codec);
+      if (_unknownFields != null) {
+        _unknownFields.WriteTo(output);
+      }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public int CalculateSize() {
+      int size = 0;
+      if (Name.Length != 0) {
+        size += 1 + pb::CodedOutputStream.ComputeStringSize(Name);
+      }
+      if (MessageName.Length != 0) {
+        size += 1 + pb::CodedOutputStream.ComputeStringSize(MessageName);
+      }
+      size += payload_.CalculateSize(_repeated_payload_codec);
+      if (_unknownFields != null) {
+        size += _unknownFields.CalculateSize();
+      }
+      return size;
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public void MergeFrom(BenchmarkDataset other) {
+      if (other == null) {
+        return;
+      }
+      if (other.Name.Length != 0) {
+        Name = other.Name;
+      }
+      if (other.MessageName.Length != 0) {
+        MessageName = other.MessageName;
+      }
+      payload_.Add(other.payload_);
+      _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public void MergeFrom(pb::CodedInputStream input) {
+      uint tag;
+      while ((tag = input.ReadTag()) != 0) {
+        switch(tag) {
+          default:
+            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
+            break;
+          case 10: {
+            Name = input.ReadString();
+            break;
+          }
+          case 18: {
+            MessageName = input.ReadString();
+            break;
+          }
+          case 26: {
+            payload_.AddEntriesFrom(input, _repeated_payload_codec);
+            break;
+          }
+        }
+      }
+    }
+
+  }
+
+  #endregion
+
+}
+
+#endregion Designer generated code
diff --git a/csharp/src/Google.Protobuf.Benchmarks/Google.Protobuf.Benchmarks.csproj b/csharp/src/Google.Protobuf.Benchmarks/Google.Protobuf.Benchmarks.csproj
new file mode 100644
index 0000000..26ad32a
--- /dev/null
+++ b/csharp/src/Google.Protobuf.Benchmarks/Google.Protobuf.Benchmarks.csproj
@@ -0,0 +1,17 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+  <PropertyGroup>
+    <OutputType>Exe</OutputType>
+    <TargetFramework>netcoreapp2.1</TargetFramework>
+  </PropertyGroup>
+
+  <ItemGroup>
+    <PackageReference Include="BenchmarkDotNet" Version="0.11.4" />
+    <ProjectReference Include="..\Google.Protobuf\Google.Protobuf.csproj" />
+  </ItemGroup>
+
+  <ItemGroup>
+    <EmbeddedResource Include="..\..\..\benchmarks\datasets\google_message1\proto3\dataset.google_message1_proto3.pb" />
+  </ItemGroup>
+
+</Project>
diff --git a/csharp/src/Google.Protobuf.Benchmarks/Program.cs b/csharp/src/Google.Protobuf.Benchmarks/Program.cs
new file mode 100644
index 0000000..66f71d1
--- /dev/null
+++ b/csharp/src/Google.Protobuf.Benchmarks/Program.cs
@@ -0,0 +1,46 @@
+#region Copyright notice and license
+// Protocol Buffers - Google's data interchange format
+// Copyright 2019 Google Inc.  All rights reserved.
+// https://github.com/protocolbuffers/protobuf
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#endregion
+
+using BenchmarkDotNet.Running;
+
+namespace Google.Protobuf.Benchmarks
+{
+    /// <summary>
+    /// Entry point, that currently runs the sole benchmark we have.
+    /// Eventually we might want to be able to specify a particular dataset
+    /// from the command line.
+    /// </summary>
+    class Program
+    {
+        static void Main() => BenchmarkRunner.Run<SerializationBenchmark>();
+    }
+}
diff --git a/csharp/src/Google.Protobuf.Benchmarks/SerializationBenchmark.cs b/csharp/src/Google.Protobuf.Benchmarks/SerializationBenchmark.cs
new file mode 100644
index 0000000..d8c2ec1
--- /dev/null
+++ b/csharp/src/Google.Protobuf.Benchmarks/SerializationBenchmark.cs
@@ -0,0 +1,120 @@
+#region Copyright notice and license
+// Protocol Buffers - Google's data interchange format
+// Copyright 2019 Google Inc.  All rights reserved.
+// https://github.com/protocolbuffers/protobuf
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#endregion
+
+using BenchmarkDotNet.Attributes;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+
+namespace Google.Protobuf.Benchmarks
+{
+    /// <summary>
+    /// Benchmark for serializing (to a MemoryStream) and deserializing (from a ByteString).
+    /// Over time we may wish to test the various different approaches to serialization and deserialization separately.
+    /// </summary>
+    [MemoryDiagnoser]
+    public class SerializationBenchmark
+    {
+        /// <summary>
+        /// All the configurations to be tested. Add more datasets to the array as they're available.
+        /// (When C# supports proto2, this will increase significantly.)
+        /// </summary>
+        public static SerializationConfig[] Configurations => new[]
+        {
+            new SerializationConfig("dataset.google_message1_proto3.pb")
+        };
+
+        [ParamsSource(nameof(Configurations))]
+        public SerializationConfig Configuration { get; set; }
+
+        private MessageParser parser;
+        /// <summary>
+        /// Each data set can contain multiple messages in a single file.
+        /// Each "write" operation should write each message in turn, and each "parse"
+        /// operation should parse each message in turn.
+        /// </summary>
+        private List<SubTest> subTests;
+
+        [GlobalSetup]
+        public void GlobalSetup()
+        {
+            parser = Configuration.Parser;
+            subTests = Configuration.Payloads.Select(p => new SubTest(p, parser.ParseFrom(p))).ToList();
+        }
+
+        [Benchmark]
+        public void WriteToStream() => subTests.ForEach(item => item.WriteToStream());
+
+        [Benchmark]
+        public void ToByteArray() => subTests.ForEach(item => item.ToByteArray());
+
+        [Benchmark]
+        public void ParseFromByteString() => subTests.ForEach(item => item.ParseFromByteString(parser));
+
+        [Benchmark]
+        public void ParseFromStream() => subTests.ForEach(item => item.ParseFromStream(parser));
+
+        private class SubTest
+        {
+            private readonly Stream destinationStream;
+            private readonly Stream sourceStream;
+            private readonly ByteString data;
+            private readonly IMessage message;
+
+            public SubTest(ByteString data, IMessage message)
+            {
+                destinationStream = new MemoryStream(data.Length);
+                sourceStream = new MemoryStream(data.ToByteArray());
+                this.data = data;
+                this.message = message;
+            }
+
+            public void Reset() => destinationStream.Position = 0;
+
+            public void WriteToStream()
+            {
+                destinationStream.Position = 0;
+                message.WriteTo(destinationStream);
+            }
+
+            public void ToByteArray() => message.ToByteArray();
+
+            public void ParseFromByteString(MessageParser parser) => parser.ParseFrom(data);
+
+            public void ParseFromStream(MessageParser parser)
+            {
+                sourceStream.Position = 0;
+                parser.ParseFrom(sourceStream);
+            }
+        }
+    }
+}
diff --git a/csharp/src/Google.Protobuf.Benchmarks/SerializationConfig.cs b/csharp/src/Google.Protobuf.Benchmarks/SerializationConfig.cs
new file mode 100644
index 0000000..679f16c
--- /dev/null
+++ b/csharp/src/Google.Protobuf.Benchmarks/SerializationConfig.cs
@@ -0,0 +1,89 @@
+#region Copyright notice and license
+// Protocol Buffers - Google's data interchange format
+// Copyright 2019 Google Inc.  All rights reserved.
+// https://github.com/protocolbuffers/protobuf
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#endregion
+
+using Benchmarks;
+using Google.Protobuf.Reflection;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Reflection;
+
+namespace Google.Protobuf.Benchmarks
+{
+    /// <summary>
+    /// The configuration for a single serialization test, loaded from a dataset.
+    /// </summary>
+    public class SerializationConfig
+    {
+        private static readonly Dictionary<string, MessageParser> parsersByMessageName = 
+            typeof(SerializationBenchmark).Assembly.GetTypes()
+                .Where(t => typeof(IMessage).IsAssignableFrom(t))
+                .ToDictionary(
+                    t => ((MessageDescriptor) t.GetProperty("Descriptor", BindingFlags.Static | BindingFlags.Public).GetValue(null)).FullName,
+                    t => ((MessageParser) t.GetProperty("Parser", BindingFlags.Static | BindingFlags.Public).GetValue(null)));
+
+        public MessageParser Parser { get; }
+        public IEnumerable<ByteString> Payloads { get; }
+        public string Name { get; }
+
+        public SerializationConfig(string resource)
+        {
+            var data = LoadData(resource);
+            var dataset = BenchmarkDataset.Parser.ParseFrom(data);
+
+            if (!parsersByMessageName.TryGetValue(dataset.MessageName, out var parser))
+            {
+                throw new ArgumentException($"No parser for message {dataset.MessageName} in this assembly");
+            }
+            Parser = parser;
+            Payloads = dataset.Payload;
+            Name = dataset.Name;
+        }
+
+        private static byte[] LoadData(string resource)
+        {
+            using (var stream = typeof(SerializationBenchmark).Assembly.GetManifestResourceStream($"Google.Protobuf.Benchmarks.{resource}"))
+            {
+                if (stream == null)
+                {
+                    throw new ArgumentException($"Unable to load embedded resource {resource}");
+                }
+                var copy = new MemoryStream();
+                stream.CopyTo(copy);
+                return copy.ToArray();
+            }
+        }
+
+        public override string ToString() => Name;
+    }
+}
diff --git a/csharp/src/Google.Protobuf.sln b/csharp/src/Google.Protobuf.sln
index 443ee3e..262a43b 100644
--- a/csharp/src/Google.Protobuf.sln
+++ b/csharp/src/Google.Protobuf.sln
@@ -2,15 +2,17 @@
 # Visual Studio 15

 VisualStudioVersion = 15.0.26114.2

 MinimumVisualStudioVersion = 10.0.40219.1

-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AddressBook", "AddressBook\AddressBook.csproj", "{AFB63919-1E05-43B4-802A-8FB8C9B2F463}"

+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AddressBook", "AddressBook\AddressBook.csproj", "{AFB63919-1E05-43B4-802A-8FB8C9B2F463}"

 EndProject

-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Google.Protobuf", "Google.Protobuf\Google.Protobuf.csproj", "{9B576380-726D-4142-8238-60A43AB0E35A}"

+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Google.Protobuf", "Google.Protobuf\Google.Protobuf.csproj", "{9B576380-726D-4142-8238-60A43AB0E35A}"

 EndProject

-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Google.Protobuf.Test", "Google.Protobuf.Test\Google.Protobuf.Test.csproj", "{580EB013-D3C7-4578-B845-015F4A3B0591}"

+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Google.Protobuf.Test", "Google.Protobuf.Test\Google.Protobuf.Test.csproj", "{580EB013-D3C7-4578-B845-015F4A3B0591}"

 EndProject

-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Google.Protobuf.Conformance", "Google.Protobuf.Conformance\Google.Protobuf.Conformance.csproj", "{DDDC055B-E185-4181-BAB0-072F0F984569}"

+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Google.Protobuf.Conformance", "Google.Protobuf.Conformance\Google.Protobuf.Conformance.csproj", "{DDDC055B-E185-4181-BAB0-072F0F984569}"

 EndProject

-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Google.Protobuf.JsonDump", "Google.Protobuf.JsonDump\Google.Protobuf.JsonDump.csproj", "{9695E08F-9829-497D-B95C-B38F28D48690}"

+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Google.Protobuf.JsonDump", "Google.Protobuf.JsonDump\Google.Protobuf.JsonDump.csproj", "{9695E08F-9829-497D-B95C-B38F28D48690}"

+EndProject

+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Google.Protobuf.Benchmarks", "Google.Protobuf.Benchmarks\Google.Protobuf.Benchmarks.csproj", "{D25E4804-4DEA-45AB-9F8C-BA4DBD8E5A07}"

 EndProject

 Global

 	GlobalSection(SolutionConfigurationPlatforms) = preSolution

@@ -38,8 +40,15 @@
 		{9695E08F-9829-497D-B95C-B38F28D48690}.Debug|Any CPU.Build.0 = Debug|Any CPU

 		{9695E08F-9829-497D-B95C-B38F28D48690}.Release|Any CPU.ActiveCfg = Release|Any CPU

 		{9695E08F-9829-497D-B95C-B38F28D48690}.Release|Any CPU.Build.0 = Release|Any CPU

+		{D25E4804-4DEA-45AB-9F8C-BA4DBD8E5A07}.Debug|Any CPU.ActiveCfg = Debug|Any CPU

+		{D25E4804-4DEA-45AB-9F8C-BA4DBD8E5A07}.Debug|Any CPU.Build.0 = Debug|Any CPU

+		{D25E4804-4DEA-45AB-9F8C-BA4DBD8E5A07}.Release|Any CPU.ActiveCfg = Release|Any CPU

+		{D25E4804-4DEA-45AB-9F8C-BA4DBD8E5A07}.Release|Any CPU.Build.0 = Release|Any CPU

 	EndGlobalSection

 	GlobalSection(SolutionProperties) = preSolution

 		HideSolutionNode = FALSE

 	EndGlobalSection

+	GlobalSection(ExtensibilityGlobals) = postSolution

+		SolutionGuid = {7B06C87B-83E1-4F5F-A0DD-6E9AFAC03DAC}

+	EndGlobalSection

 EndGlobal