Merge pull request #3026 from stanley-cheung/php_update_gen_code_test

PHP: fix interop stub construction after codegen change
diff --git a/.gitmodules b/.gitmodules
index 4ab7f3c..2d0c009 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -8,7 +8,7 @@
 [submodule "third_party/protobuf"]
 	path = third_party/protobuf
 	url = https://github.com/google/protobuf.git
-	branch = v3.0.0-alpha-3
+	branch = v3.0.0-beta-1
 [submodule "third_party/gflags"]
 	path = third_party/gflags
 	url = https://github.com/gflags/gflags.git
diff --git a/doc/interop-test-descriptions.md b/doc/interop-test-descriptions.md
index 84ceaa3..75110e8 100644
--- a/doc/interop-test-descriptions.md
+++ b/doc/interop-test-descriptions.md
@@ -91,6 +91,87 @@
 * clients are free to assert that the response payload body contents are zero
   and comparing the entire response message against a golden response
 
+### large_compressed_unary
+
+This test verifies compressed unary calls succeed in sending messages. It
+sends one unary request for every combination of compression algorithm and
+payload type.
+
+In all scenarios, whether compression was actually performed is determined by
+the compression bit in the response's message flags. The response's compression
+value indicates which algorithm was used if said compression bit is set.
+
+
+Server features:
+* [UnaryCall][]
+* [Compressable Payload][]
+* [Uncompressable Payload][]
+* [Random Payload][]
+
+Procedure:
+ 1. Client calls UnaryCall with:
+
+    ```
+    {
+      response_compression: <one of {NONE, GZIP, DEFLATE}>
+      response_type: COMPRESSABLE
+      response_size: 314159
+      payload:{
+        body: 271828 bytes of zeros
+      }
+    }
+    ```
+    Client asserts:
+    * call was successful
+    * response payload type is COMPRESSABLE
+    * response compression is consistent with the requested one.
+    * if `response_compression == NONE`, the response MUST NOT have the
+      compressed message flag set.
+    * if `response_compression != NONE`, the response MUST have the compressed
+      message flag set.
+    * response payload body is 314159 bytes in size
+    * clients are free to assert that the response payload body contents are
+      zero and comparing the entire response message against a golden response
+
+
+ 2. Client calls UnaryCall with:
+    ```
+    {
+      response_compression: <one of {NONE, GZIP, DEFLATE}>
+      response_type: UNCOMPRESSABLE
+      response_size: 314159
+      payload:{
+        body: 271828 bytes of zeros
+      }
+    }
+    ```
+    Client asserts:
+    * call was successful
+    * response payload type is UNCOMPRESSABLE
+    * response compression is consistent with the requested one.
+    * the response MUST NOT have the compressed message flag set.
+    * response payload body is 314159 bytes in size
+    * clients are free to assert that the response payload body contents are
+      identical to the golden uncompressable data at `test/cpp/interop/rnd.dat`.
+
+
+ 3. Client calls UnaryCall with:
+    ```
+    {
+      response_compression: <one of {NONE, GZIP, DEFLATE}>
+      response_type: RANDOM
+      response_size: 314159
+      payload:{
+        body: 271828 bytes of zeros
+      }
+    }
+    ```
+    Client asserts:
+    * call was successful
+    * response payload type is either COMPRESSABLE or UNCOMPRESSABLE
+    * the behavior is consistent with the randomly chosen incoming payload type,
+      as described in their respective sections.
+
 ### client_streaming
 
 This test verifies that client-only streaming succeeds.
@@ -184,6 +265,112 @@
 * clients are free to assert that the response payload body contents are zero
   and comparing the entire response messages against golden responses
 
+### server_compressed_streaming
+
+This test verifies that server-only compressed streaming succeeds.
+
+Server features:
+* [StreamingOutputCall][]
+* [Compressable Payload][]
+* [Uncompressable Payload][]
+* [Random Payload][]
+
+
+Procedure:
+ 1. Client calls StreamingOutputCall with:
+
+    ```
+    {
+      response_compression: <one of {NONE, GZIP, DEFLATE}>
+      response_type:COMPRESSABLE
+      response_parameters:{
+        size: 31415
+      }
+      response_parameters:{
+        size: 9
+      }
+      response_parameters:{
+        size: 2653
+      }
+      response_parameters:{
+        size: 58979
+      }
+    }
+    ```
+
+    Client asserts:
+    * call was successful
+    * exactly four responses
+    * response payloads are COMPRESSABLE
+    * response compression is consistent with the requested one.
+    * if `response_compression == NONE`, the response MUST NOT have the
+      compressed message flag set.
+    * if `response_compression != NONE`, the response MUST have the compressed
+      message flag set.
+    * response payload bodies are sized (in order): 31415, 9, 2653, 58979
+    * clients are free to assert that the response payload body contents are
+      zero and comparing the entire response messages against golden responses
+
+
+ 2. Client calls StreamingOutputCall with:
+
+    ```
+    {
+      response_compression: <one of {NONE, GZIP, DEFLATE}>
+      response_type:UNCOMPRESSABLE
+      response_parameters:{
+        size: 31415
+      }
+      response_parameters:{
+        size: 9
+      }
+      response_parameters:{
+        size: 2653
+      }
+      response_parameters:{
+        size: 58979
+      }
+    }
+    ```
+
+    Client asserts:
+    * call was successful
+    * exactly four responses
+    * response payloads are UNCOMPRESSABLE
+    * response compressions are consistent with the requested one.
+    * the responses MUST NOT have the compressed message flag set.
+    * response payload bodies are sized (in order): 31415, 9, 2653, 58979
+    * clients are free to assert that the body of the responses are identical to
+      the golden uncompressable data at `test/cpp/interop/rnd.dat`.
+
+
+ 3. Client calls StreamingOutputCall with:
+
+    ```
+    {
+      response_compression: <one of {NONE, GZIP, DEFLATE}>
+      response_type:RANDOM
+      response_parameters:{
+        size: 31415
+      }
+      response_parameters:{
+        size: 9
+      }
+      response_parameters:{
+        size: 2653
+      }
+      response_parameters:{
+        size: 58979
+      }
+    }
+    ```
+
+    Client asserts:
+    * call was successful
+    * response payload type is either COMPRESSABLE or UNCOMPRESSABLE
+    * the behavior is consistent with the randomly chosen incoming payload type,
+      as described in their respective sections.
+
 ### ping_pong
 
 This test verifies that full duplex bidi is supported.
@@ -825,6 +1012,21 @@
 of the size requested containing all zeros and the payload type is
 COMPRESSABLE.
 
+### Uncompressable Payload
+[Uncompressable Payload]: #uncompressable-payload
+
+When the client requests UNCOMPRESSABLE payload, the response includes a payload
+of the size requested containing uncompressable data and the payload type is
+UNCOMPRESSABLE. A 512 kB dump from /dev/urandom is the current golden data,
+stored at `test/cpp/interop/rnd.dat`
+
+### Random Payload
+[Random Payload]: #random-payload
+
+When the client requests RANDOM payload, the response includes either a randomly
+chosen COMPRESSABLE or UNCOMPRESSABLE payload. The data and the payload type
+will be consistent with this choice.
+
 ### Echo Status
 [Echo Status]: #echo-status
 When the client sends a response_status in the request payload, the server closes
diff --git a/include/grpc/grpc.h b/include/grpc/grpc.h
index 145052b..a75f356 100644
--- a/include/grpc/grpc.h
+++ b/include/grpc/grpc.h
@@ -214,8 +214,7 @@
 
   /** The following fields are reserved for grpc internal use.
       There is no need to initialize them, and they will be set to garbage
-     during
-      calls to grpc. */
+      during calls to grpc. */
   struct {
     void *obfuscated[4];
   } internal_data;
diff --git a/include/grpc/grpc_security.h b/include/grpc/grpc_security.h
index de565b2..6ee6933 100644
--- a/include/grpc/grpc_security.h
+++ b/include/grpc/grpc_security.h
@@ -89,16 +89,18 @@
      key and certificate chain. This parameter can be NULL if the client does
      not have such a key/cert pair. */
 grpc_credentials *grpc_ssl_credentials_create(
-    const char *pem_root_certs, grpc_ssl_pem_key_cert_pair *pem_key_cert_pair);
+    const char *pem_root_certs, grpc_ssl_pem_key_cert_pair *pem_key_cert_pair,
+    void *reserved);
 
 /* Creates a composite credentials object. */
 grpc_credentials *grpc_composite_credentials_create(grpc_credentials *creds1,
-                                                    grpc_credentials *creds2);
+                                                    grpc_credentials *creds2,
+                                                    void *reserved);
 
 /* Creates a compute engine credentials object.
    WARNING: Do NOT use this credentials to connect to a non-google service as
    this could result in an oauth2 token leak. */
-grpc_credentials *grpc_compute_engine_credentials_create(void);
+grpc_credentials *grpc_compute_engine_credentials_create(void *reserved);
 
 extern const gpr_timespec grpc_max_auth_token_lifetime;
 
@@ -112,7 +114,8 @@
      account credentials.  It should not exceed grpc_max_auth_token_lifetime
      or will be cropped to this value.  */
 grpc_credentials *grpc_service_account_credentials_create(
-    const char *json_key, const char *scope, gpr_timespec token_lifetime);
+    const char *json_key, const char *scope, gpr_timespec token_lifetime,
+    void *reserved);
 
 /* Creates a JWT credentials object. May return NULL if the input is invalid.
    - json_key is the JSON key string containing the client's private key.
@@ -120,7 +123,7 @@
      this credentials.  It should not exceed grpc_max_auth_token_lifetime or
      will be cropped to this value.  */
 grpc_credentials *grpc_service_account_jwt_access_credentials_create(
-    const char *json_key, gpr_timespec token_lifetime);
+    const char *json_key, gpr_timespec token_lifetime, void *reserved);
 
 /* Creates an Oauth2 Refresh Token credentials object. May return NULL if the
    input is invalid.
@@ -129,23 +132,25 @@
    - json_refresh_token is the JSON string containing the refresh token itself
      along with a client_id and client_secret. */
 grpc_credentials *grpc_refresh_token_credentials_create(
-    const char *json_refresh_token);
+    const char *json_refresh_token, void *reserved);
 
 /* Creates an Oauth2 Access Token credentials with an access token that was
    aquired by an out of band mechanism. */
 grpc_credentials *grpc_access_token_credentials_create(
-    const char *access_token);
+    const char *access_token, void *reserved);
 
 /* Creates an IAM credentials object. */
 grpc_credentials *grpc_iam_credentials_create(const char *authorization_token,
-                                              const char *authority_selector);
+                                              const char *authority_selector,
+                                              void *reserved);
 
 /* --- Secure channel creation. --- */
 
 /* Creates a secure channel using the passed-in credentials. */
 grpc_channel *grpc_secure_channel_create(grpc_credentials *creds,
                                          const char *target,
-                                         const grpc_channel_args *args);
+                                         const grpc_channel_args *args,
+                                         void *reserved);
 
 /* --- grpc_server_credentials object. ---
 
@@ -171,7 +176,7 @@
      NULL. */
 grpc_server_credentials *grpc_ssl_server_credentials_create(
     const char *pem_root_certs, grpc_ssl_pem_key_cert_pair *pem_key_cert_pairs,
-    size_t num_key_cert_pairs, int force_client_auth);
+    size_t num_key_cert_pairs, int force_client_auth, void *reserved);
 
 /* --- Server-side secure ports. --- */
 
diff --git a/src/compiler/csharp_generator.cc b/src/compiler/csharp_generator.cc
index 9432bdd..51d8d98 100644
--- a/src/compiler/csharp_generator.cc
+++ b/src/compiler/csharp_generator.cc
@@ -35,10 +35,16 @@
 #include <map>
 #include <vector>
 
+#include "src/compiler/csharp_generator.h"
 #include "src/compiler/config.h"
 #include "src/compiler/csharp_generator_helpers.h"
 #include "src/compiler/csharp_generator.h"
 
+
+using google::protobuf::compiler::csharp::GetFileNamespace;
+using google::protobuf::compiler::csharp::GetClassName;
+using google::protobuf::compiler::csharp::GetUmbrellaClassName;
+using google::protobuf::SimpleItoa;
 using grpc::protobuf::FileDescriptor;
 using grpc::protobuf::Descriptor;
 using grpc::protobuf::ServiceDescriptor;
@@ -55,47 +61,10 @@
 using std::map;
 using std::vector;
 
+
 namespace grpc_csharp_generator {
 namespace {
 
-// TODO(jtattermusch): make GetFileNamespace part of libprotoc public API.
-// NOTE: Implementation needs to match exactly to GetFileNamespace
-// defined in csharp_helpers.h in protoc csharp plugin.
-// We cannot reference it directly because google3 protobufs
-// don't have a csharp protoc plugin.
-std::string GetFileNamespace(const FileDescriptor* file) {
-  if (file->options().has_csharp_namespace()) {
-    return file->options().csharp_namespace();
-  }
-  return file->package();
-}
-
-std::string ToCSharpName(const std::string& name, const FileDescriptor* file) {
-  std::string result = GetFileNamespace(file);
-  if (result != "") {
-    result += '.';
-  }
-  std::string classname;
-  if (file->package().empty()) {
-    classname = name;
-  } else {
-    // Strip the proto package from full_name since we've replaced it with
-    // the C# namespace.
-    classname = name.substr(file->package().size() + 1);
-  }
-  result += StringReplace(classname, ".", ".Types.", false);
-  return "global::" + result;
-}
-
-// TODO(jtattermusch): make GetClassName part of libprotoc public API.
-// NOTE: Implementation needs to match exactly to GetClassName
-// defined in csharp_helpers.h in protoc csharp plugin.
-// We cannot reference it directly because google3 protobufs
-// don't have a csharp protoc plugin.
-std::string GetClassName(const Descriptor* message) {
-  return ToCSharpName(message->full_name(), message->file());
-}
-
 std::string GetServiceClassName(const ServiceDescriptor* service) {
   return service->name();
 }
@@ -229,7 +198,7 @@
   for (size_t i = 0; i < used_messages.size(); i++) {
     const Descriptor *message = used_messages[i];
     out->Print(
-        "static readonly Marshaller<$type$> $fieldname$ = Marshallers.Create((arg) => arg.ToByteArray(), $type$.ParseFrom);\n",
+        "static readonly Marshaller<$type$> $fieldname$ = Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), $type$.Parser.ParseFrom);\n",
         "fieldname", GetMarshallerFieldName(message), "type",
         GetClassName(message));
   }
@@ -258,6 +227,16 @@
   out->Outdent();
 }
 
+void GenerateServiceDescriptorProperty(Printer* out, const ServiceDescriptor *service) {
+  out->Print("// service descriptor\n");
+  out->Print("public static global::Google.Protobuf.Reflection.ServiceDescriptor Descriptor\n");
+  out->Print("{\n");
+  out->Print("  get { return $umbrella$.Descriptor.Services[$index$]; }\n",
+             "umbrella", GetUmbrellaClassName(service->file()), "index", SimpleItoa(service->index()));
+  out->Print("}\n");
+  out->Print("\n");
+}
+
 void GenerateClientInterface(Printer* out, const ServiceDescriptor *service) {
   out->Print("// client interface\n");
   out->Print("public interface $name$\n", "name",
@@ -504,6 +483,7 @@
   for (int i = 0; i < service->method_count(); i++) {
     GenerateStaticMethodField(out, service->method(i));
   }
+  GenerateServiceDescriptorProperty(out, service);
   GenerateClientInterface(out, service);
   GenerateServerInterface(out, service);
   GenerateClientStub(out, service);
@@ -539,7 +519,6 @@
     out.Print("using System.Threading;\n");
     out.Print("using System.Threading.Tasks;\n");
     out.Print("using Grpc.Core;\n");
-    // TODO(jtattermusch): add using for protobuf message classes
     out.Print("\n");
 
     out.Print("namespace $namespace$ {\n", "namespace", GetFileNamespace(file));
diff --git a/src/compiler/csharp_generator.h b/src/compiler/csharp_generator.h
index ec537d3..67e3ee3 100644
--- a/src/compiler/csharp_generator.h
+++ b/src/compiler/csharp_generator.h
@@ -36,6 +36,11 @@
 
 #include "src/compiler/config.h"
 
+using namespace std;
+
+#include <google/protobuf/compiler/csharp/csharp_names.h>
+#include <google/protobuf/stubs/strutil.h>
+
 namespace grpc_csharp_generator {
 
 grpc::string GetServices(const grpc::protobuf::FileDescriptor *file);
diff --git a/src/core/security/client_auth_filter.c b/src/core/security/client_auth_filter.c
index 8e63978..f3ecfd0 100644
--- a/src/core/security/client_auth_filter.c
+++ b/src/core/security/client_auth_filter.c
@@ -153,7 +153,8 @@
   }
 
   if (channel_creds_has_md && call_creds_has_md) {
-    calld->creds = grpc_composite_credentials_create(channel_creds, ctx->creds);
+    calld->creds =
+        grpc_composite_credentials_create(channel_creds, ctx->creds, NULL);
     if (calld->creds == NULL) {
       bubble_up_error(elem, GRPC_STATUS_INVALID_ARGUMENT,
                       "Incompatible credentials set on channel and call.");
diff --git a/src/core/security/credentials.c b/src/core/security/credentials.c
index 8852cab..362d5f4 100644
--- a/src/core/security/credentials.c
+++ b/src/core/security/credentials.c
@@ -298,8 +298,10 @@
 }
 
 grpc_credentials *grpc_ssl_credentials_create(
-    const char *pem_root_certs, grpc_ssl_pem_key_cert_pair *pem_key_cert_pair) {
+    const char *pem_root_certs, grpc_ssl_pem_key_cert_pair *pem_key_cert_pair,
+    void *reserved) {
   grpc_ssl_credentials *c = gpr_malloc(sizeof(grpc_ssl_credentials));
+  GPR_ASSERT(reserved == NULL);
   memset(c, 0, sizeof(grpc_ssl_credentials));
   c->base.type = GRPC_CREDENTIALS_TYPE_SSL;
   c->base.vtable = &ssl_vtable;
@@ -310,9 +312,11 @@
 
 grpc_server_credentials *grpc_ssl_server_credentials_create(
     const char *pem_root_certs, grpc_ssl_pem_key_cert_pair *pem_key_cert_pairs,
-    size_t num_key_cert_pairs, int force_client_auth) {
+    size_t num_key_cert_pairs, int force_client_auth, void *reserved) {
   grpc_ssl_server_credentials *c =
       gpr_malloc(sizeof(grpc_ssl_server_credentials));
+  GPR_ASSERT(reserved == NULL);
+  memset(c, 0, sizeof(grpc_ssl_credentials));
   memset(c, 0, sizeof(grpc_ssl_server_credentials));
   c->base.type = GRPC_CREDENTIALS_TYPE_SSL;
   c->base.vtable = &ssl_server_vtable;
@@ -430,7 +434,8 @@
 }
 
 grpc_credentials *grpc_service_account_jwt_access_credentials_create(
-    const char *json_key, gpr_timespec token_lifetime) {
+    const char *json_key, gpr_timespec token_lifetime, void *reserved) {
+  GPR_ASSERT(reserved == NULL);
   return grpc_service_account_jwt_access_credentials_create_from_auth_json_key(
       grpc_auth_json_key_create_from_string(json_key), token_lifetime);
 }
@@ -635,9 +640,10 @@
                    metadata_req);
 }
 
-grpc_credentials *grpc_compute_engine_credentials_create(void) {
+grpc_credentials *grpc_compute_engine_credentials_create(void *reserved) {
   grpc_oauth2_token_fetcher_credentials *c =
       gpr_malloc(sizeof(grpc_oauth2_token_fetcher_credentials));
+  GPR_ASSERT(reserved == NULL);
   init_oauth2_token_fetcher(c, compute_engine_fetch_oauth2);
   c->base.vtable = &compute_engine_vtable;
   return &c->base;
@@ -693,10 +699,11 @@
 }
 
 grpc_credentials *grpc_service_account_credentials_create(
-    const char *json_key, const char *scope, gpr_timespec token_lifetime) {
+    const char *json_key, const char *scope, gpr_timespec token_lifetime,
+    void *reserved) {
   grpc_service_account_credentials *c;
   grpc_auth_json_key key = grpc_auth_json_key_create_from_string(json_key);
-
+  GPR_ASSERT(reserved == NULL);
   if (scope == NULL || (strlen(scope) == 0) ||
       !grpc_auth_json_key_is_valid(&key)) {
     gpr_log(GPR_ERROR,
@@ -766,7 +773,8 @@
 }
 
 grpc_credentials *grpc_refresh_token_credentials_create(
-    const char *json_refresh_token) {
+    const char *json_refresh_token, void *reserved) {
+  GPR_ASSERT(reserved == NULL);
   return grpc_refresh_token_credentials_create_from_auth_refresh_token(
       grpc_auth_refresh_token_create_from_string(json_refresh_token));
 }
@@ -867,11 +875,12 @@
     access_token_has_request_metadata_only, access_token_get_request_metadata,
     NULL};
 
-grpc_credentials *grpc_access_token_credentials_create(
-    const char *access_token) {
+grpc_credentials *grpc_access_token_credentials_create(const char *access_token,
+                                                       void *reserved) {
   grpc_access_token_credentials *c =
       gpr_malloc(sizeof(grpc_access_token_credentials));
   char *token_md_value;
+  GPR_ASSERT(reserved == NULL);
   memset(c, 0, sizeof(grpc_access_token_credentials));
   c->base.type = GRPC_CREDENTIALS_TYPE_OAUTH2;
   c->base.vtable = &access_token_vtable;
@@ -1101,12 +1110,14 @@
 }
 
 grpc_credentials *grpc_composite_credentials_create(grpc_credentials *creds1,
-                                                    grpc_credentials *creds2) {
+                                                    grpc_credentials *creds2,
+                                                    void *reserved) {
   size_t i;
   size_t creds_array_byte_size;
   grpc_credentials_array creds1_array;
   grpc_credentials_array creds2_array;
   grpc_composite_credentials *c;
+  GPR_ASSERT(reserved == NULL);
   GPR_ASSERT(creds1 != NULL);
   GPR_ASSERT(creds2 != NULL);
   c = gpr_malloc(sizeof(grpc_composite_credentials));
@@ -1209,8 +1220,10 @@
     iam_get_request_metadata, NULL};
 
 grpc_credentials *grpc_iam_credentials_create(const char *token,
-                                              const char *authority_selector) {
+                                              const char *authority_selector,
+                                              void *reserved) {
   grpc_iam_credentials *c;
+  GPR_ASSERT(reserved == NULL);
   GPR_ASSERT(token != NULL);
   GPR_ASSERT(authority_selector != NULL);
   c = gpr_malloc(sizeof(grpc_iam_credentials));
diff --git a/src/core/security/google_default_credentials.c b/src/core/security/google_default_credentials.c
index 3631de8..f9aa518 100644
--- a/src/core/security/google_default_credentials.c
+++ b/src/core/security/google_default_credentials.c
@@ -194,7 +194,7 @@
     int need_compute_engine_creds = is_stack_running_on_compute_engine();
     compute_engine_detection_done = 1;
     if (need_compute_engine_creds) {
-      result = grpc_compute_engine_credentials_create();
+      result = grpc_compute_engine_credentials_create(NULL);
     }
   }
 
@@ -202,9 +202,9 @@
   if (!serving_cached_credentials && result != NULL) {
     /* Blend with default ssl credentials and add a global reference so that it
        can be cached and re-served. */
-    grpc_credentials *ssl_creds = grpc_ssl_credentials_create(NULL, NULL);
+    grpc_credentials *ssl_creds = grpc_ssl_credentials_create(NULL, NULL, NULL);
     default_credentials = grpc_credentials_ref(
-        grpc_composite_credentials_create(ssl_creds, result));
+        grpc_composite_credentials_create(ssl_creds, result, NULL));
     GPR_ASSERT(default_credentials != NULL);
     grpc_credentials_unref(ssl_creds);
     grpc_credentials_unref(result);
diff --git a/src/core/support/log_win32.c b/src/core/support/log_win32.c
index 629781d..b68239f 100644
--- a/src/core/support/log_win32.c
+++ b/src/core/support/log_win32.c
@@ -81,10 +81,18 @@
 
 /* Simple starter implementation */
 void gpr_default_log(gpr_log_func_args *args) {
+  char *final_slash;
+  const char *display_file;
   char time_buffer[64];
   gpr_timespec now = gpr_now(GPR_CLOCK_REALTIME);
   struct tm tm;
 
+  final_slash = strrchr(args->file, '\\');
+  if (final_slash == NULL)
+    display_file = args->file;
+  else
+    display_file = final_slash + 1;
+
   if (localtime_s(&tm, &now.tv_sec)) {
     strcpy(time_buffer, "error:localtime");
   } else if (0 ==
@@ -94,7 +102,7 @@
 
   fprintf(stderr, "%s%s.%09u %5lu %s:%d] %s\n",
           gpr_log_severity_string(args->severity), time_buffer,
-          (int)(now.tv_nsec), GetCurrentThreadId(), args->file, args->line,
+          (int)(now.tv_nsec), GetCurrentThreadId(), display_file, args->line,
           args->message);
 }
 
diff --git a/src/core/surface/secure_channel_create.c b/src/core/surface/secure_channel_create.c
index eccee24..35b60bd 100644
--- a/src/core/surface/secure_channel_create.c
+++ b/src/core/surface/secure_channel_create.c
@@ -185,7 +185,8 @@
                    - perform handshakes */
 grpc_channel *grpc_secure_channel_create(grpc_credentials *creds,
                                          const char *target,
-                                         const grpc_channel_args *args) {
+                                         const grpc_channel_args *args,
+                                         void *reserved) {
   grpc_channel *channel;
   grpc_arg connector_arg;
   grpc_channel_args *args_copy;
@@ -198,6 +199,7 @@
   const grpc_channel_filter *filters[MAX_FILTERS];
   int n = 0;
 
+  GPR_ASSERT(reserved == NULL);
   if (grpc_find_security_connector_in_args(args) != NULL) {
     gpr_log(GPR_ERROR, "Cannot set security context in channel args.");
     return grpc_lame_client_channel_create(
diff --git a/src/cpp/client/secure_credentials.cc b/src/cpp/client/secure_credentials.cc
index f368f25..e064246 100644
--- a/src/cpp/client/secure_credentials.cc
+++ b/src/cpp/client/secure_credentials.cc
@@ -46,7 +46,8 @@
   args.SetChannelArgs(&channel_args);
   return CreateChannelInternal(
       args.GetSslTargetNameOverride(),
-      grpc_secure_channel_create(c_creds_, target.c_str(), &channel_args));
+      grpc_secure_channel_create(c_creds_, target.c_str(), &channel_args,
+                                 nullptr));
 }
 
 bool SecureCredentials::ApplyToCall(grpc_call* call) {
@@ -75,14 +76,14 @@
 
   grpc_credentials* c_creds = grpc_ssl_credentials_create(
       options.pem_root_certs.empty() ? nullptr : options.pem_root_certs.c_str(),
-      options.pem_private_key.empty() ? nullptr : &pem_key_cert_pair);
+      options.pem_private_key.empty() ? nullptr : &pem_key_cert_pair, nullptr);
   return WrapCredentials(c_creds);
 }
 
 // Builds credentials for use when running in GCE
 std::shared_ptr<Credentials> ComputeEngineCredentials() {
   GrpcLibrary init;  // To call grpc_init().
-  return WrapCredentials(grpc_compute_engine_credentials_create());
+  return WrapCredentials(grpc_compute_engine_credentials_create(nullptr));
 }
 
 // Builds service account credentials.
@@ -99,7 +100,7 @@
   gpr_timespec lifetime =
       gpr_time_from_seconds(token_lifetime_seconds, GPR_TIMESPAN);
   return WrapCredentials(grpc_service_account_credentials_create(
-      json_key.c_str(), scope.c_str(), lifetime));
+      json_key.c_str(), scope.c_str(), lifetime, nullptr));
 }
 
 // Builds JWT credentials.
@@ -114,15 +115,15 @@
   gpr_timespec lifetime =
       gpr_time_from_seconds(token_lifetime_seconds, GPR_TIMESPAN);
   return WrapCredentials(grpc_service_account_jwt_access_credentials_create(
-      json_key.c_str(), lifetime));
+      json_key.c_str(), lifetime, nullptr));
 }
 
 // Builds refresh token credentials.
 std::shared_ptr<Credentials> RefreshTokenCredentials(
     const grpc::string& json_refresh_token) {
   GrpcLibrary init;  // To call grpc_init().
-  return WrapCredentials(
-      grpc_refresh_token_credentials_create(json_refresh_token.c_str()));
+  return WrapCredentials(grpc_refresh_token_credentials_create(
+      json_refresh_token.c_str(), nullptr));
 }
 
 // Builds access token credentials.
@@ -130,7 +131,7 @@
     const grpc::string& access_token) {
   GrpcLibrary init;  // To call grpc_init().
   return WrapCredentials(
-      grpc_access_token_credentials_create(access_token.c_str()));
+      grpc_access_token_credentials_create(access_token.c_str(), nullptr));
 }
 
 // Builds IAM credentials.
@@ -139,7 +140,7 @@
     const grpc::string& authority_selector) {
   GrpcLibrary init;  // To call grpc_init().
   return WrapCredentials(grpc_iam_credentials_create(
-      authorization_token.c_str(), authority_selector.c_str()));
+      authorization_token.c_str(), authority_selector.c_str(), nullptr));
 }
 
 // Combines two credentials objects into a composite credentials.
@@ -154,7 +155,7 @@
   SecureCredentials* s2 = creds2->AsSecureCredentials();
   if (s1 && s2) {
     return WrapCredentials(grpc_composite_credentials_create(
-        s1->GetRawCreds(), s2->GetRawCreds()));
+        s1->GetRawCreds(), s2->GetRawCreds(), nullptr));
   }
   return nullptr;
 }
diff --git a/src/cpp/server/secure_server_credentials.cc b/src/cpp/server/secure_server_credentials.cc
index f203cf7..5bce9ca 100644
--- a/src/cpp/server/secure_server_credentials.cc
+++ b/src/cpp/server/secure_server_credentials.cc
@@ -52,7 +52,7 @@
   grpc_server_credentials* c_creds = grpc_ssl_server_credentials_create(
       options.pem_root_certs.empty() ? nullptr : options.pem_root_certs.c_str(),
       &pem_key_cert_pairs[0], pem_key_cert_pairs.size(),
-      options.force_client_auth);
+      options.force_client_auth, nullptr);
   return std::shared_ptr<ServerCredentials>(
       new SecureServerCredentials(c_creds));
 }
diff --git a/src/csharp/.gitignore b/src/csharp/.gitignore
index 48365e3..deac550 100644
--- a/src/csharp/.gitignore
+++ b/src/csharp/.gitignore
@@ -4,6 +4,9 @@
 test-results
 packages
 Grpc.v12.suo
+Grpc.sdf
+
 TestResult.xml
 /TestResults
+.vs/
 *.nupkg
diff --git a/src/csharp/Grpc.Core/VersionInfo.cs b/src/csharp/Grpc.Core/VersionInfo.cs
index b6dbd3b..eda821b 100644
--- a/src/csharp/Grpc.Core/VersionInfo.cs
+++ b/src/csharp/Grpc.Core/VersionInfo.cs
@@ -39,8 +39,8 @@
     public static class VersionInfo
     {
         /// <summary>
-        /// Current version of gRPC
+        /// Current version of gRPC C#
         /// </summary>
-        public const string CurrentVersion = "0.6.1";
+        public const string CurrentVersion = "0.7.0";
     }
 }
diff --git a/src/csharp/Grpc.Examples.MathClient/MathClient.cs b/src/csharp/Grpc.Examples.MathClient/MathClient.cs
index abd95cb..01e4a80 100644
--- a/src/csharp/Grpc.Examples.MathClient/MathClient.cs
+++ b/src/csharp/Grpc.Examples.MathClient/MathClient.cs
@@ -33,7 +33,7 @@
 using System.Threading;
 using Grpc.Core;
 
-namespace math
+namespace Math
 {
     class MathClient
     {
diff --git a/src/csharp/Grpc.Examples.MathServer/MathServer.cs b/src/csharp/Grpc.Examples.MathServer/MathServer.cs
index 26bef64..6e974a0 100644
--- a/src/csharp/Grpc.Examples.MathServer/MathServer.cs
+++ b/src/csharp/Grpc.Examples.MathServer/MathServer.cs
@@ -34,7 +34,7 @@
 using System.Threading;
 using Grpc.Core;
 
-namespace math
+namespace Math
 {
     class MainClass
     {
diff --git a/src/csharp/Grpc.Examples.Tests/Grpc.Examples.Tests.csproj b/src/csharp/Grpc.Examples.Tests/Grpc.Examples.Tests.csproj
index 9a8f780..c4c1ee6 100644
--- a/src/csharp/Grpc.Examples.Tests/Grpc.Examples.Tests.csproj
+++ b/src/csharp/Grpc.Examples.Tests/Grpc.Examples.Tests.csproj
@@ -37,13 +37,14 @@
     <AssemblyOriginatorKeyFile>C:\keys\Grpc.snk</AssemblyOriginatorKeyFile>
   </PropertyGroup>
   <ItemGroup>
+    <Reference Include="Google.Protobuf, Version=3.0.0.0, Culture=neutral, PublicKeyToken=a7d26565bac4d604, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\packages\Google.Protobuf.3.0.0-alpha4\lib\portable-net45+netcore45+wpa81+wp8\Google.Protobuf.dll</HintPath>
+    </Reference>
     <Reference Include="nunit.framework">
       <HintPath>..\packages\NUnit.2.6.4\lib\nunit.framework.dll</HintPath>
     </Reference>
     <Reference Include="System" />
-    <Reference Include="Google.ProtocolBuffers">
-      <HintPath>..\packages\Google.ProtocolBuffers.2.4.1.521\lib\net40\Google.ProtocolBuffers.dll</HintPath>
-    </Reference>
     <Reference Include="System.Interactive.Async, Version=1.2.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
       <SpecificVersion>False</SpecificVersion>
       <HintPath>..\packages\Ix-Async.1.2.3\lib\net45\System.Interactive.Async.dll</HintPath>
diff --git a/src/csharp/Grpc.Examples.Tests/MathClientServerTests.cs b/src/csharp/Grpc.Examples.Tests/MathClientServerTests.cs
index 36c1c94..d8547758 100644
--- a/src/csharp/Grpc.Examples.Tests/MathClientServerTests.cs
+++ b/src/csharp/Grpc.Examples.Tests/MathClientServerTests.cs
@@ -40,7 +40,7 @@
 using Grpc.Core.Utils;
 using NUnit.Framework;
 
-namespace math.Tests
+namespace Math.Tests
 {
     /// <summary>
     /// Math client talks to local math server.
@@ -75,7 +75,7 @@
         [Test]
         public void Div1()
         {
-            DivReply response = client.Div(new DivArgs.Builder { Dividend = 10, Divisor = 3 }.Build());
+            DivReply response = client.Div(new DivArgs { Dividend = 10, Divisor = 3 });
             Assert.AreEqual(3, response.Quotient);
             Assert.AreEqual(1, response.Remainder);
         }
@@ -83,7 +83,7 @@
         [Test]
         public void Div2()
         {
-            DivReply response = client.Div(new DivArgs.Builder { Dividend = 0, Divisor = 1 }.Build());
+            DivReply response = client.Div(new DivArgs { Dividend = 0, Divisor = 1 });
             Assert.AreEqual(0, response.Quotient);
             Assert.AreEqual(0, response.Remainder);
         }
@@ -91,14 +91,14 @@
         [Test]
         public void DivByZero()
         {
-            var ex = Assert.Throws<RpcException>(() => client.Div(new DivArgs.Builder { Dividend = 0, Divisor = 0 }.Build()));
+            var ex = Assert.Throws<RpcException>(() => client.Div(new DivArgs { Dividend = 0, Divisor = 0 }));
             Assert.AreEqual(StatusCode.Unknown, ex.Status.StatusCode);
         }
 
         [Test]
         public async Task DivAsync()
         {
-            DivReply response = await client.DivAsync(new DivArgs.Builder { Dividend = 10, Divisor = 3 }.Build());
+            DivReply response = await client.DivAsync(new DivArgs { Dividend = 10, Divisor = 3 });
             Assert.AreEqual(3, response.Quotient);
             Assert.AreEqual(1, response.Remainder);
         }
@@ -106,7 +106,7 @@
         [Test]
         public async Task Fib()
         {
-            using (var call = client.Fib(new FibArgs.Builder { Limit = 6 }.Build()))
+            using (var call = client.Fib(new FibArgs { Limit = 6 }))
             {
                 var responses = await call.ResponseStream.ToListAsync();
                 CollectionAssert.AreEqual(new List<long> { 1, 1, 2, 3, 5, 8 },
@@ -119,8 +119,7 @@
         {
             var cts = new CancellationTokenSource();
 
-            using (var call = client.Fib(new FibArgs.Builder { Limit = 0 }.Build(), 
-                cancellationToken: cts.Token))
+            using (var call = client.Fib(new FibArgs { Limit = 0 }, cancellationToken: cts.Token))
             {
                 List<long> responses = new List<long>();
 
@@ -147,7 +146,7 @@
         [Test]
         public async Task FibWithDeadline()
         {
-            using (var call = client.Fib(new FibArgs.Builder { Limit = 0 }.Build(), 
+            using (var call = client.Fib(new FibArgs { Limit = 0 }, 
                 deadline: DateTime.UtcNow.AddMilliseconds(500)))
             {
                 var ex = Assert.Throws<RpcException>(async () => await call.ResponseStream.ToListAsync());
@@ -163,8 +162,7 @@
         {
             using (var call = client.Sum())
             {
-                var numbers = new List<long> { 10, 20, 30 }.ConvertAll(
-                            n => Num.CreateBuilder().SetNum_(n).Build());
+                var numbers = new List<long> { 10, 20, 30 }.ConvertAll(n => new Num{ Num_ = n });
 
                 await call.RequestStream.WriteAllAsync(numbers);
                 var result = await call.ResponseAsync;
@@ -177,9 +175,9 @@
         {
             var divArgsList = new List<DivArgs>
             {
-                new DivArgs.Builder { Dividend = 10, Divisor = 3 }.Build(),
-                new DivArgs.Builder { Dividend = 100, Divisor = 21 }.Build(),
-                new DivArgs.Builder { Dividend = 7, Divisor = 2 }.Build()
+                new DivArgs { Dividend = 10, Divisor = 3 },
+                new DivArgs { Dividend = 100, Divisor = 21 },
+                new DivArgs { Dividend = 7, Divisor = 2 }
             };
 
             using (var call = client.DivMany())
diff --git a/src/csharp/Grpc.Examples.Tests/packages.config b/src/csharp/Grpc.Examples.Tests/packages.config
index cc6e9af..7266fa1 100644
--- a/src/csharp/Grpc.Examples.Tests/packages.config
+++ b/src/csharp/Grpc.Examples.Tests/packages.config
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>

 <packages>

-  <package id="Google.ProtocolBuffers" version="2.4.1.521" targetFramework="net45" />

+  <package id="Google.Protobuf" version="3.0.0-alpha4" targetFramework="net45" />

   <package id="Ix-Async" version="1.2.3" targetFramework="net45" />

   <package id="NUnit" version="2.6.4" targetFramework="net45" />

 </packages>
\ No newline at end of file
diff --git a/src/csharp/Grpc.Examples/Grpc.Examples.csproj b/src/csharp/Grpc.Examples/Grpc.Examples.csproj
index c1aa405..55462e0 100644
--- a/src/csharp/Grpc.Examples/Grpc.Examples.csproj
+++ b/src/csharp/Grpc.Examples/Grpc.Examples.csproj
@@ -37,11 +37,12 @@
     <AssemblyOriginatorKeyFile>C:\keys\Grpc.snk</AssemblyOriginatorKeyFile>
   </PropertyGroup>
   <ItemGroup>
+    <Reference Include="Google.Protobuf, Version=3.0.0.0, Culture=neutral, PublicKeyToken=a7d26565bac4d604, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\packages\Google.Protobuf.3.0.0-alpha4\lib\portable-net45+netcore45+wpa81+wp8\Google.Protobuf.dll</HintPath>
+    </Reference>
     <Reference Include="System" />
     <Reference Include="System.Data.Linq" />
-    <Reference Include="Google.ProtocolBuffers">
-      <HintPath>..\packages\Google.ProtocolBuffers.2.4.1.521\lib\net40\Google.ProtocolBuffers.dll</HintPath>
-    </Reference>
     <Reference Include="System.Interactive.Async">
       <HintPath>..\packages\Ix-Async.1.2.3\lib\net45\System.Interactive.Async.dll</HintPath>
     </Reference>
diff --git a/src/csharp/Grpc.Examples/Math.cs b/src/csharp/Grpc.Examples/Math.cs
index 75b1e9d..d0e1ee8 100644
--- a/src/csharp/Grpc.Examples/Math.cs
+++ b/src/csharp/Grpc.Examples/Math.cs
@@ -1,80 +1,46 @@
-// Generated by ProtoGen, Version=2.4.1.521, Culture=neutral, PublicKeyToken=17b3b1f090c3ea48.  DO NOT EDIT!
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: math.proto
 #pragma warning disable 1591, 0612, 3021
 #region Designer generated code
 
-using pb = global::Google.ProtocolBuffers;
-using pbc = global::Google.ProtocolBuffers.Collections;
-using pbd = global::Google.ProtocolBuffers.Descriptors;
+using pb = global::Google.Protobuf;
+using pbc = global::Google.Protobuf.Collections;
+using pbr = global::Google.Protobuf.Reflection;
 using scg = global::System.Collections.Generic;
-namespace math {
+namespace Math {
 
   namespace Proto {
 
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
     public static partial class Math {
 
-      #region Extension registration
-      public static void RegisterAllExtensions(pb::ExtensionRegistry registry) {
-      }
-      #endregion
-      #region Static variables
-      internal static pbd::MessageDescriptor internal__static_math_DivArgs__Descriptor;
-      internal static pb::FieldAccess.FieldAccessorTable<global::math.DivArgs, global::math.DivArgs.Builder> internal__static_math_DivArgs__FieldAccessorTable;
-      internal static pbd::MessageDescriptor internal__static_math_DivReply__Descriptor;
-      internal static pb::FieldAccess.FieldAccessorTable<global::math.DivReply, global::math.DivReply.Builder> internal__static_math_DivReply__FieldAccessorTable;
-      internal static pbd::MessageDescriptor internal__static_math_FibArgs__Descriptor;
-      internal static pb::FieldAccess.FieldAccessorTable<global::math.FibArgs, global::math.FibArgs.Builder> internal__static_math_FibArgs__FieldAccessorTable;
-      internal static pbd::MessageDescriptor internal__static_math_Num__Descriptor;
-      internal static pb::FieldAccess.FieldAccessorTable<global::math.Num, global::math.Num.Builder> internal__static_math_Num__FieldAccessorTable;
-      internal static pbd::MessageDescriptor internal__static_math_FibReply__Descriptor;
-      internal static pb::FieldAccess.FieldAccessorTable<global::math.FibReply, global::math.FibReply.Builder> internal__static_math_FibReply__FieldAccessorTable;
-      #endregion
       #region Descriptor
-      public static pbd::FileDescriptor Descriptor {
+      public static pbr::FileDescriptor Descriptor {
         get { return descriptor; }
       }
-      private static pbd::FileDescriptor descriptor;
+      private static pbr::FileDescriptor descriptor;
 
       static Math() {
         byte[] descriptorData = global::System.Convert.FromBase64String(
             string.Concat(
-              "CgptYXRoLnByb3RvEgRtYXRoIiwKB0RpdkFyZ3MSEAoIZGl2aWRlbmQYASAB",
-              "KAMSDwoHZGl2aXNvchgCIAEoAyIvCghEaXZSZXBseRIQCghxdW90aWVudBgB",
-              "IAEoAxIRCglyZW1haW5kZXIYAiABKAMiGAoHRmliQXJncxINCgVsaW1pdBgB",
-              "IAEoAyISCgNOdW0SCwoDbnVtGAEgASgDIhkKCEZpYlJlcGx5Eg0KBWNvdW50",
-              "GAEgASgDMqQBCgRNYXRoEiYKA0RpdhINLm1hdGguRGl2QXJncxoOLm1hdGgu",
-              "RGl2UmVwbHkiABIuCgdEaXZNYW55Eg0ubWF0aC5EaXZBcmdzGg4ubWF0aC5E",
-              "aXZSZXBseSIAKAEwARIjCgNGaWISDS5tYXRoLkZpYkFyZ3MaCS5tYXRoLk51",
-            "bSIAMAESHwoDU3VtEgkubWF0aC5OdW0aCS5tYXRoLk51bSIAKAE="));
-        pbd::FileDescriptor.InternalDescriptorAssigner assigner = delegate(pbd::FileDescriptor root) {
-          descriptor = root;
-          internal__static_math_DivArgs__Descriptor = Descriptor.MessageTypes[0];
-          internal__static_math_DivArgs__FieldAccessorTable =
-              new pb::FieldAccess.FieldAccessorTable<global::math.DivArgs, global::math.DivArgs.Builder>(internal__static_math_DivArgs__Descriptor,
-                  new string[] { "Dividend", "Divisor", });
-          internal__static_math_DivReply__Descriptor = Descriptor.MessageTypes[1];
-          internal__static_math_DivReply__FieldAccessorTable =
-              new pb::FieldAccess.FieldAccessorTable<global::math.DivReply, global::math.DivReply.Builder>(internal__static_math_DivReply__Descriptor,
-                  new string[] { "Quotient", "Remainder", });
-          internal__static_math_FibArgs__Descriptor = Descriptor.MessageTypes[2];
-          internal__static_math_FibArgs__FieldAccessorTable =
-              new pb::FieldAccess.FieldAccessorTable<global::math.FibArgs, global::math.FibArgs.Builder>(internal__static_math_FibArgs__Descriptor,
-                  new string[] { "Limit", });
-          internal__static_math_Num__Descriptor = Descriptor.MessageTypes[3];
-          internal__static_math_Num__FieldAccessorTable =
-              new pb::FieldAccess.FieldAccessorTable<global::math.Num, global::math.Num.Builder>(internal__static_math_Num__Descriptor,
-                  new string[] { "Num_", });
-          internal__static_math_FibReply__Descriptor = Descriptor.MessageTypes[4];
-          internal__static_math_FibReply__FieldAccessorTable =
-              new pb::FieldAccess.FieldAccessorTable<global::math.FibReply, global::math.FibReply.Builder>(internal__static_math_FibReply__Descriptor,
-                  new string[] { "Count", });
-          pb::ExtensionRegistry registry = pb::ExtensionRegistry.CreateInstance();
-          RegisterAllExtensions(registry);
-          return registry;
-        };
-        pbd::FileDescriptor.InternalBuildGeneratedFileFrom(descriptorData,
-            new pbd::FileDescriptor[] {
-            }, assigner);
+              "CgptYXRoLnByb3RvEgRtYXRoIiwKB0RpdkFyZ3MSEAoIZGl2aWRlbmQYASAB", 
+              "KAMSDwoHZGl2aXNvchgCIAEoAyIvCghEaXZSZXBseRIQCghxdW90aWVudBgB", 
+              "IAEoAxIRCglyZW1haW5kZXIYAiABKAMiGAoHRmliQXJncxINCgVsaW1pdBgB", 
+              "IAEoAyISCgNOdW0SCwoDbnVtGAEgASgDIhkKCEZpYlJlcGx5Eg0KBWNvdW50", 
+              "GAEgASgDMqQBCgRNYXRoEiYKA0RpdhINLm1hdGguRGl2QXJncxoOLm1hdGgu", 
+              "RGl2UmVwbHkiABIuCgdEaXZNYW55Eg0ubWF0aC5EaXZBcmdzGg4ubWF0aC5E", 
+              "aXZSZXBseSIAKAEwARIjCgNGaWISDS5tYXRoLkZpYkFyZ3MaCS5tYXRoLk51", 
+              "bSIAMAESHwoDU3VtEgkubWF0aC5OdW0aCS5tYXRoLk51bSIAKAFiBnByb3Rv", 
+              "Mw=="));
+        descriptor = pbr::FileDescriptor.InternalBuildGeneratedFileFrom(descriptorData,
+            new pbr::FileDescriptor[] { },
+            new pbr::GeneratedCodeInfo(null, new pbr::GeneratedCodeInfo[] {
+              new pbr::GeneratedCodeInfo(typeof(global::Math.DivArgs), new[]{ "Dividend", "Divisor" }, null, null, null),
+              new pbr::GeneratedCodeInfo(typeof(global::Math.DivReply), new[]{ "Quotient", "Remainder" }, null, null, null),
+              new pbr::GeneratedCodeInfo(typeof(global::Math.FibArgs), new[]{ "Limit" }, null, null, null),
+              new pbr::GeneratedCodeInfo(typeof(global::Math.Num), new[]{ "Num_" }, null, null, null),
+              new pbr::GeneratedCodeInfo(typeof(global::Math.FibReply), new[]{ "Count" }, null, null, null)
+            }));
       }
       #endregion
 
@@ -82,1450 +48,569 @@
   }
   #region Messages
   [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
-  public sealed partial class DivArgs : pb::GeneratedMessage<DivArgs, DivArgs.Builder> {
-    private DivArgs() { }
-    private static readonly DivArgs defaultInstance = new DivArgs().MakeReadOnly();
-    private static readonly string[] _divArgsFieldNames = new string[] { "dividend", "divisor" };
-    private static readonly uint[] _divArgsFieldTags = new uint[] { 8, 16 };
-    public static DivArgs DefaultInstance {
-      get { return defaultInstance; }
+  public sealed partial class DivArgs : pb::IMessage<DivArgs> {
+    private static readonly pb::MessageParser<DivArgs> _parser = new pb::MessageParser<DivArgs>(() => new DivArgs());
+    public static pb::MessageParser<DivArgs> Parser { get { return _parser; } }
+
+    public static pbr::MessageDescriptor Descriptor {
+      get { return global::Math.Proto.Math.Descriptor.MessageTypes[0]; }
     }
 
-    public override DivArgs DefaultInstanceForType {
-      get { return DefaultInstance; }
+    pbr::MessageDescriptor pb::IMessage.Descriptor {
+      get { return Descriptor; }
     }
 
-    protected override DivArgs ThisMessage {
-      get { return this; }
+    public DivArgs() {
+      OnConstruction();
     }
 
-    public static pbd::MessageDescriptor Descriptor {
-      get { return global::math.Proto.Math.internal__static_math_DivArgs__Descriptor; }
+    partial void OnConstruction();
+
+    public DivArgs(DivArgs other) : this() {
+      dividend_ = other.dividend_;
+      divisor_ = other.divisor_;
     }
 
-    protected override pb::FieldAccess.FieldAccessorTable<DivArgs, DivArgs.Builder> InternalFieldAccessors {
-      get { return global::math.Proto.Math.internal__static_math_DivArgs__FieldAccessorTable; }
+    public DivArgs Clone() {
+      return new DivArgs(this);
     }
 
     public const int DividendFieldNumber = 1;
-    private bool hasDividend;
     private long dividend_;
-    public bool HasDividend {
-      get { return hasDividend; }
-    }
     public long Dividend {
       get { return dividend_; }
+      set {
+        dividend_ = value;
+      }
     }
 
     public const int DivisorFieldNumber = 2;
-    private bool hasDivisor;
     private long divisor_;
-    public bool HasDivisor {
-      get { return hasDivisor; }
-    }
     public long Divisor {
       get { return divisor_; }
+      set {
+        divisor_ = value;
+      }
     }
 
-    public override bool IsInitialized {
-      get {
+    public override bool Equals(object other) {
+      return Equals(other as DivArgs);
+    }
+
+    public bool Equals(DivArgs other) {
+      if (ReferenceEquals(other, null)) {
+        return false;
+      }
+      if (ReferenceEquals(other, this)) {
         return true;
       }
+      if (Dividend != other.Dividend) return false;
+      if (Divisor != other.Divisor) return false;
+      return true;
     }
 
-    public override void WriteTo(pb::ICodedOutputStream output) {
-      int size = SerializedSize;
-      string[] field_names = _divArgsFieldNames;
-      if (hasDividend) {
-        output.WriteInt64(1, field_names[0], Dividend);
-      }
-      if (hasDivisor) {
-        output.WriteInt64(2, field_names[1], Divisor);
-      }
-      UnknownFields.WriteTo(output);
+    public override int GetHashCode() {
+      int hash = 1;
+      if (Dividend != 0L) hash ^= Dividend.GetHashCode();
+      if (Divisor != 0L) hash ^= Divisor.GetHashCode();
+      return hash;
     }
 
-    private int memoizedSerializedSize = -1;
-    public override int SerializedSize {
-      get {
-        int size = memoizedSerializedSize;
-        if (size != -1) return size;
+    public override string ToString() {
+      return pb::JsonFormatter.Default.Format(this);
+    }
 
-        size = 0;
-        if (hasDividend) {
-          size += pb::CodedOutputStream.ComputeInt64Size(1, Dividend);
-        }
-        if (hasDivisor) {
-          size += pb::CodedOutputStream.ComputeInt64Size(2, Divisor);
-        }
-        size += UnknownFields.SerializedSize;
-        memoizedSerializedSize = size;
-        return size;
+    public void WriteTo(pb::CodedOutputStream output) {
+      if (Dividend != 0L) {
+        output.WriteRawTag(8);
+        output.WriteInt64(Dividend);
+      }
+      if (Divisor != 0L) {
+        output.WriteRawTag(16);
+        output.WriteInt64(Divisor);
       }
     }
 
-    public static DivArgs ParseFrom(pb::ByteString data) {
-      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
-    }
-    public static DivArgs ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
-      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
-    }
-    public static DivArgs ParseFrom(byte[] data) {
-      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
-    }
-    public static DivArgs ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
-      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
-    }
-    public static DivArgs ParseFrom(global::System.IO.Stream input) {
-      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
-    }
-    public static DivArgs ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
-      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
-    }
-    public static DivArgs ParseDelimitedFrom(global::System.IO.Stream input) {
-      return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
-    }
-    public static DivArgs ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
-      return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
-    }
-    public static DivArgs ParseFrom(pb::ICodedInputStream input) {
-      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
-    }
-    public static DivArgs ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
-      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
-    }
-    private DivArgs MakeReadOnly() {
-      return this;
+    public int CalculateSize() {
+      int size = 0;
+      if (Dividend != 0L) {
+        size += 1 + pb::CodedOutputStream.ComputeInt64Size(Dividend);
+      }
+      if (Divisor != 0L) {
+        size += 1 + pb::CodedOutputStream.ComputeInt64Size(Divisor);
+      }
+      return size;
     }
 
-    public static Builder CreateBuilder() { return new Builder(); }
-    public override Builder ToBuilder() { return CreateBuilder(this); }
-    public override Builder CreateBuilderForType() { return new Builder(); }
-    public static Builder CreateBuilder(DivArgs prototype) {
-      return new Builder(prototype);
+    public void MergeFrom(DivArgs other) {
+      if (other == null) {
+        return;
+      }
+      if (other.Dividend != 0L) {
+        Dividend = other.Dividend;
+      }
+      if (other.Divisor != 0L) {
+        Divisor = other.Divisor;
+      }
     }
 
-    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
-    public sealed partial class Builder : pb::GeneratedBuilder<DivArgs, Builder> {
-      protected override Builder ThisBuilder {
-        get { return this; }
-      }
-      public Builder() {
-        result = DefaultInstance;
-        resultIsReadOnly = true;
-      }
-      internal Builder(DivArgs cloneFrom) {
-        result = cloneFrom;
-        resultIsReadOnly = true;
-      }
-
-      private bool resultIsReadOnly;
-      private DivArgs result;
-
-      private DivArgs PrepareBuilder() {
-        if (resultIsReadOnly) {
-          DivArgs original = result;
-          result = new DivArgs();
-          resultIsReadOnly = false;
-          MergeFrom(original);
-        }
-        return result;
-      }
-
-      public override bool IsInitialized {
-        get { return result.IsInitialized; }
-      }
-
-      protected override DivArgs MessageBeingBuilt {
-        get { return PrepareBuilder(); }
-      }
-
-      public override Builder Clear() {
-        result = DefaultInstance;
-        resultIsReadOnly = true;
-        return this;
-      }
-
-      public override Builder Clone() {
-        if (resultIsReadOnly) {
-          return new Builder(result);
-        } else {
-          return new Builder().MergeFrom(result);
-        }
-      }
-
-      public override pbd::MessageDescriptor DescriptorForType {
-        get { return global::math.DivArgs.Descriptor; }
-      }
-
-      public override DivArgs DefaultInstanceForType {
-        get { return global::math.DivArgs.DefaultInstance; }
-      }
-
-      public override DivArgs BuildPartial() {
-        if (resultIsReadOnly) {
-          return result;
-        }
-        resultIsReadOnly = true;
-        return result.MakeReadOnly();
-      }
-
-      public override Builder MergeFrom(pb::IMessage other) {
-        if (other is DivArgs) {
-          return MergeFrom((DivArgs) other);
-        } else {
-          base.MergeFrom(other);
-          return this;
-        }
-      }
-
-      public override Builder MergeFrom(DivArgs other) {
-        if (other == global::math.DivArgs.DefaultInstance) return this;
-        PrepareBuilder();
-        if (other.HasDividend) {
-          Dividend = other.Dividend;
-        }
-        if (other.HasDivisor) {
-          Divisor = other.Divisor;
-        }
-        this.MergeUnknownFields(other.UnknownFields);
-        return this;
-      }
-
-      public override Builder MergeFrom(pb::ICodedInputStream input) {
-        return MergeFrom(input, pb::ExtensionRegistry.Empty);
-      }
-
-      public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
-        PrepareBuilder();
-        pb::UnknownFieldSet.Builder unknownFields = null;
-        uint tag;
-        string field_name;
-        while (input.ReadTag(out tag, out field_name)) {
-          if(tag == 0 && field_name != null) {
-            int field_ordinal = global::System.Array.BinarySearch(_divArgsFieldNames, field_name, global::System.StringComparer.Ordinal);
-            if(field_ordinal >= 0)
-              tag = _divArgsFieldTags[field_ordinal];
-            else {
-              if (unknownFields == null) {
-                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
-              }
-              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);
-              continue;
-            }
+    public void MergeFrom(pb::CodedInputStream input) {
+      uint tag;
+      while ((tag = input.ReadTag()) != 0) {
+        switch(tag) {
+          default:
+            input.SkipLastField();
+            break;
+          case 8: {
+            Dividend = input.ReadInt64();
+            break;
           }
-          switch (tag) {
-            case 0: {
-              throw pb::InvalidProtocolBufferException.InvalidTag();
-            }
-            default: {
-              if (pb::WireFormat.IsEndGroupTag(tag)) {
-                if (unknownFields != null) {
-                  this.UnknownFields = unknownFields.Build();
-                }
-                return this;
-              }
-              if (unknownFields == null) {
-                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
-              }
-              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);
-              break;
-            }
-            case 8: {
-              result.hasDividend = input.ReadInt64(ref result.dividend_);
-              break;
-            }
-            case 16: {
-              result.hasDivisor = input.ReadInt64(ref result.divisor_);
-              break;
-            }
+          case 16: {
+            Divisor = input.ReadInt64();
+            break;
           }
         }
-
-        if (unknownFields != null) {
-          this.UnknownFields = unknownFields.Build();
-        }
-        return this;
-      }
-
-
-      public bool HasDividend {
-        get { return result.hasDividend; }
-      }
-      public long Dividend {
-        get { return result.Dividend; }
-        set { SetDividend(value); }
-      }
-      public Builder SetDividend(long value) {
-        PrepareBuilder();
-        result.hasDividend = true;
-        result.dividend_ = value;
-        return this;
-      }
-      public Builder ClearDividend() {
-        PrepareBuilder();
-        result.hasDividend = false;
-        result.dividend_ = 0L;
-        return this;
-      }
-
-      public bool HasDivisor {
-        get { return result.hasDivisor; }
-      }
-      public long Divisor {
-        get { return result.Divisor; }
-        set { SetDivisor(value); }
-      }
-      public Builder SetDivisor(long value) {
-        PrepareBuilder();
-        result.hasDivisor = true;
-        result.divisor_ = value;
-        return this;
-      }
-      public Builder ClearDivisor() {
-        PrepareBuilder();
-        result.hasDivisor = false;
-        result.divisor_ = 0L;
-        return this;
       }
     }
-    static DivArgs() {
-      object.ReferenceEquals(global::math.Proto.Math.Descriptor, null);
-    }
+
   }
 
   [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
-  public sealed partial class DivReply : pb::GeneratedMessage<DivReply, DivReply.Builder> {
-    private DivReply() { }
-    private static readonly DivReply defaultInstance = new DivReply().MakeReadOnly();
-    private static readonly string[] _divReplyFieldNames = new string[] { "quotient", "remainder" };
-    private static readonly uint[] _divReplyFieldTags = new uint[] { 8, 16 };
-    public static DivReply DefaultInstance {
-      get { return defaultInstance; }
+  public sealed partial class DivReply : pb::IMessage<DivReply> {
+    private static readonly pb::MessageParser<DivReply> _parser = new pb::MessageParser<DivReply>(() => new DivReply());
+    public static pb::MessageParser<DivReply> Parser { get { return _parser; } }
+
+    public static pbr::MessageDescriptor Descriptor {
+      get { return global::Math.Proto.Math.Descriptor.MessageTypes[1]; }
     }
 
-    public override DivReply DefaultInstanceForType {
-      get { return DefaultInstance; }
+    pbr::MessageDescriptor pb::IMessage.Descriptor {
+      get { return Descriptor; }
     }
 
-    protected override DivReply ThisMessage {
-      get { return this; }
+    public DivReply() {
+      OnConstruction();
     }
 
-    public static pbd::MessageDescriptor Descriptor {
-      get { return global::math.Proto.Math.internal__static_math_DivReply__Descriptor; }
+    partial void OnConstruction();
+
+    public DivReply(DivReply other) : this() {
+      quotient_ = other.quotient_;
+      remainder_ = other.remainder_;
     }
 
-    protected override pb::FieldAccess.FieldAccessorTable<DivReply, DivReply.Builder> InternalFieldAccessors {
-      get { return global::math.Proto.Math.internal__static_math_DivReply__FieldAccessorTable; }
+    public DivReply Clone() {
+      return new DivReply(this);
     }
 
     public const int QuotientFieldNumber = 1;
-    private bool hasQuotient;
     private long quotient_;
-    public bool HasQuotient {
-      get { return hasQuotient; }
-    }
     public long Quotient {
       get { return quotient_; }
+      set {
+        quotient_ = value;
+      }
     }
 
     public const int RemainderFieldNumber = 2;
-    private bool hasRemainder;
     private long remainder_;
-    public bool HasRemainder {
-      get { return hasRemainder; }
-    }
     public long Remainder {
       get { return remainder_; }
+      set {
+        remainder_ = value;
+      }
     }
 
-    public override bool IsInitialized {
-      get {
+    public override bool Equals(object other) {
+      return Equals(other as DivReply);
+    }
+
+    public bool Equals(DivReply other) {
+      if (ReferenceEquals(other, null)) {
+        return false;
+      }
+      if (ReferenceEquals(other, this)) {
         return true;
       }
+      if (Quotient != other.Quotient) return false;
+      if (Remainder != other.Remainder) return false;
+      return true;
     }
 
-    public override void WriteTo(pb::ICodedOutputStream output) {
-      int size = SerializedSize;
-      string[] field_names = _divReplyFieldNames;
-      if (hasQuotient) {
-        output.WriteInt64(1, field_names[0], Quotient);
-      }
-      if (hasRemainder) {
-        output.WriteInt64(2, field_names[1], Remainder);
-      }
-      UnknownFields.WriteTo(output);
+    public override int GetHashCode() {
+      int hash = 1;
+      if (Quotient != 0L) hash ^= Quotient.GetHashCode();
+      if (Remainder != 0L) hash ^= Remainder.GetHashCode();
+      return hash;
     }
 
-    private int memoizedSerializedSize = -1;
-    public override int SerializedSize {
-      get {
-        int size = memoizedSerializedSize;
-        if (size != -1) return size;
+    public override string ToString() {
+      return pb::JsonFormatter.Default.Format(this);
+    }
 
-        size = 0;
-        if (hasQuotient) {
-          size += pb::CodedOutputStream.ComputeInt64Size(1, Quotient);
-        }
-        if (hasRemainder) {
-          size += pb::CodedOutputStream.ComputeInt64Size(2, Remainder);
-        }
-        size += UnknownFields.SerializedSize;
-        memoizedSerializedSize = size;
-        return size;
+    public void WriteTo(pb::CodedOutputStream output) {
+      if (Quotient != 0L) {
+        output.WriteRawTag(8);
+        output.WriteInt64(Quotient);
+      }
+      if (Remainder != 0L) {
+        output.WriteRawTag(16);
+        output.WriteInt64(Remainder);
       }
     }
 
-    public static DivReply ParseFrom(pb::ByteString data) {
-      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
-    }
-    public static DivReply ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
-      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
-    }
-    public static DivReply ParseFrom(byte[] data) {
-      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
-    }
-    public static DivReply ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
-      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
-    }
-    public static DivReply ParseFrom(global::System.IO.Stream input) {
-      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
-    }
-    public static DivReply ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
-      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
-    }
-    public static DivReply ParseDelimitedFrom(global::System.IO.Stream input) {
-      return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
-    }
-    public static DivReply ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
-      return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
-    }
-    public static DivReply ParseFrom(pb::ICodedInputStream input) {
-      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
-    }
-    public static DivReply ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
-      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
-    }
-    private DivReply MakeReadOnly() {
-      return this;
+    public int CalculateSize() {
+      int size = 0;
+      if (Quotient != 0L) {
+        size += 1 + pb::CodedOutputStream.ComputeInt64Size(Quotient);
+      }
+      if (Remainder != 0L) {
+        size += 1 + pb::CodedOutputStream.ComputeInt64Size(Remainder);
+      }
+      return size;
     }
 
-    public static Builder CreateBuilder() { return new Builder(); }
-    public override Builder ToBuilder() { return CreateBuilder(this); }
-    public override Builder CreateBuilderForType() { return new Builder(); }
-    public static Builder CreateBuilder(DivReply prototype) {
-      return new Builder(prototype);
+    public void MergeFrom(DivReply other) {
+      if (other == null) {
+        return;
+      }
+      if (other.Quotient != 0L) {
+        Quotient = other.Quotient;
+      }
+      if (other.Remainder != 0L) {
+        Remainder = other.Remainder;
+      }
     }
 
-    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
-    public sealed partial class Builder : pb::GeneratedBuilder<DivReply, Builder> {
-      protected override Builder ThisBuilder {
-        get { return this; }
-      }
-      public Builder() {
-        result = DefaultInstance;
-        resultIsReadOnly = true;
-      }
-      internal Builder(DivReply cloneFrom) {
-        result = cloneFrom;
-        resultIsReadOnly = true;
-      }
-
-      private bool resultIsReadOnly;
-      private DivReply result;
-
-      private DivReply PrepareBuilder() {
-        if (resultIsReadOnly) {
-          DivReply original = result;
-          result = new DivReply();
-          resultIsReadOnly = false;
-          MergeFrom(original);
-        }
-        return result;
-      }
-
-      public override bool IsInitialized {
-        get { return result.IsInitialized; }
-      }
-
-      protected override DivReply MessageBeingBuilt {
-        get { return PrepareBuilder(); }
-      }
-
-      public override Builder Clear() {
-        result = DefaultInstance;
-        resultIsReadOnly = true;
-        return this;
-      }
-
-      public override Builder Clone() {
-        if (resultIsReadOnly) {
-          return new Builder(result);
-        } else {
-          return new Builder().MergeFrom(result);
-        }
-      }
-
-      public override pbd::MessageDescriptor DescriptorForType {
-        get { return global::math.DivReply.Descriptor; }
-      }
-
-      public override DivReply DefaultInstanceForType {
-        get { return global::math.DivReply.DefaultInstance; }
-      }
-
-      public override DivReply BuildPartial() {
-        if (resultIsReadOnly) {
-          return result;
-        }
-        resultIsReadOnly = true;
-        return result.MakeReadOnly();
-      }
-
-      public override Builder MergeFrom(pb::IMessage other) {
-        if (other is DivReply) {
-          return MergeFrom((DivReply) other);
-        } else {
-          base.MergeFrom(other);
-          return this;
-        }
-      }
-
-      public override Builder MergeFrom(DivReply other) {
-        if (other == global::math.DivReply.DefaultInstance) return this;
-        PrepareBuilder();
-        if (other.HasQuotient) {
-          Quotient = other.Quotient;
-        }
-        if (other.HasRemainder) {
-          Remainder = other.Remainder;
-        }
-        this.MergeUnknownFields(other.UnknownFields);
-        return this;
-      }
-
-      public override Builder MergeFrom(pb::ICodedInputStream input) {
-        return MergeFrom(input, pb::ExtensionRegistry.Empty);
-      }
-
-      public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
-        PrepareBuilder();
-        pb::UnknownFieldSet.Builder unknownFields = null;
-        uint tag;
-        string field_name;
-        while (input.ReadTag(out tag, out field_name)) {
-          if(tag == 0 && field_name != null) {
-            int field_ordinal = global::System.Array.BinarySearch(_divReplyFieldNames, field_name, global::System.StringComparer.Ordinal);
-            if(field_ordinal >= 0)
-              tag = _divReplyFieldTags[field_ordinal];
-            else {
-              if (unknownFields == null) {
-                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
-              }
-              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);
-              continue;
-            }
+    public void MergeFrom(pb::CodedInputStream input) {
+      uint tag;
+      while ((tag = input.ReadTag()) != 0) {
+        switch(tag) {
+          default:
+            input.SkipLastField();
+            break;
+          case 8: {
+            Quotient = input.ReadInt64();
+            break;
           }
-          switch (tag) {
-            case 0: {
-              throw pb::InvalidProtocolBufferException.InvalidTag();
-            }
-            default: {
-              if (pb::WireFormat.IsEndGroupTag(tag)) {
-                if (unknownFields != null) {
-                  this.UnknownFields = unknownFields.Build();
-                }
-                return this;
-              }
-              if (unknownFields == null) {
-                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
-              }
-              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);
-              break;
-            }
-            case 8: {
-              result.hasQuotient = input.ReadInt64(ref result.quotient_);
-              break;
-            }
-            case 16: {
-              result.hasRemainder = input.ReadInt64(ref result.remainder_);
-              break;
-            }
+          case 16: {
+            Remainder = input.ReadInt64();
+            break;
           }
         }
-
-        if (unknownFields != null) {
-          this.UnknownFields = unknownFields.Build();
-        }
-        return this;
-      }
-
-
-      public bool HasQuotient {
-        get { return result.hasQuotient; }
-      }
-      public long Quotient {
-        get { return result.Quotient; }
-        set { SetQuotient(value); }
-      }
-      public Builder SetQuotient(long value) {
-        PrepareBuilder();
-        result.hasQuotient = true;
-        result.quotient_ = value;
-        return this;
-      }
-      public Builder ClearQuotient() {
-        PrepareBuilder();
-        result.hasQuotient = false;
-        result.quotient_ = 0L;
-        return this;
-      }
-
-      public bool HasRemainder {
-        get { return result.hasRemainder; }
-      }
-      public long Remainder {
-        get { return result.Remainder; }
-        set { SetRemainder(value); }
-      }
-      public Builder SetRemainder(long value) {
-        PrepareBuilder();
-        result.hasRemainder = true;
-        result.remainder_ = value;
-        return this;
-      }
-      public Builder ClearRemainder() {
-        PrepareBuilder();
-        result.hasRemainder = false;
-        result.remainder_ = 0L;
-        return this;
       }
     }
-    static DivReply() {
-      object.ReferenceEquals(global::math.Proto.Math.Descriptor, null);
-    }
+
   }
 
   [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
-  public sealed partial class FibArgs : pb::GeneratedMessage<FibArgs, FibArgs.Builder> {
-    private FibArgs() { }
-    private static readonly FibArgs defaultInstance = new FibArgs().MakeReadOnly();
-    private static readonly string[] _fibArgsFieldNames = new string[] { "limit" };
-    private static readonly uint[] _fibArgsFieldTags = new uint[] { 8 };
-    public static FibArgs DefaultInstance {
-      get { return defaultInstance; }
+  public sealed partial class FibArgs : pb::IMessage<FibArgs> {
+    private static readonly pb::MessageParser<FibArgs> _parser = new pb::MessageParser<FibArgs>(() => new FibArgs());
+    public static pb::MessageParser<FibArgs> Parser { get { return _parser; } }
+
+    public static pbr::MessageDescriptor Descriptor {
+      get { return global::Math.Proto.Math.Descriptor.MessageTypes[2]; }
     }
 
-    public override FibArgs DefaultInstanceForType {
-      get { return DefaultInstance; }
+    pbr::MessageDescriptor pb::IMessage.Descriptor {
+      get { return Descriptor; }
     }
 
-    protected override FibArgs ThisMessage {
-      get { return this; }
+    public FibArgs() {
+      OnConstruction();
     }
 
-    public static pbd::MessageDescriptor Descriptor {
-      get { return global::math.Proto.Math.internal__static_math_FibArgs__Descriptor; }
+    partial void OnConstruction();
+
+    public FibArgs(FibArgs other) : this() {
+      limit_ = other.limit_;
     }
 
-    protected override pb::FieldAccess.FieldAccessorTable<FibArgs, FibArgs.Builder> InternalFieldAccessors {
-      get { return global::math.Proto.Math.internal__static_math_FibArgs__FieldAccessorTable; }
+    public FibArgs Clone() {
+      return new FibArgs(this);
     }
 
     public const int LimitFieldNumber = 1;
-    private bool hasLimit;
     private long limit_;
-    public bool HasLimit {
-      get { return hasLimit; }
-    }
     public long Limit {
       get { return limit_; }
+      set {
+        limit_ = value;
+      }
     }
 
-    public override bool IsInitialized {
-      get {
+    public override bool Equals(object other) {
+      return Equals(other as FibArgs);
+    }
+
+    public bool Equals(FibArgs other) {
+      if (ReferenceEquals(other, null)) {
+        return false;
+      }
+      if (ReferenceEquals(other, this)) {
         return true;
       }
+      if (Limit != other.Limit) return false;
+      return true;
     }
 
-    public override void WriteTo(pb::ICodedOutputStream output) {
-      int size = SerializedSize;
-      string[] field_names = _fibArgsFieldNames;
-      if (hasLimit) {
-        output.WriteInt64(1, field_names[0], Limit);
-      }
-      UnknownFields.WriteTo(output);
+    public override int GetHashCode() {
+      int hash = 1;
+      if (Limit != 0L) hash ^= Limit.GetHashCode();
+      return hash;
     }
 
-    private int memoizedSerializedSize = -1;
-    public override int SerializedSize {
-      get {
-        int size = memoizedSerializedSize;
-        if (size != -1) return size;
+    public override string ToString() {
+      return pb::JsonFormatter.Default.Format(this);
+    }
 
-        size = 0;
-        if (hasLimit) {
-          size += pb::CodedOutputStream.ComputeInt64Size(1, Limit);
-        }
-        size += UnknownFields.SerializedSize;
-        memoizedSerializedSize = size;
-        return size;
+    public void WriteTo(pb::CodedOutputStream output) {
+      if (Limit != 0L) {
+        output.WriteRawTag(8);
+        output.WriteInt64(Limit);
       }
     }
 
-    public static FibArgs ParseFrom(pb::ByteString data) {
-      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
-    }
-    public static FibArgs ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
-      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
-    }
-    public static FibArgs ParseFrom(byte[] data) {
-      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
-    }
-    public static FibArgs ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
-      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
-    }
-    public static FibArgs ParseFrom(global::System.IO.Stream input) {
-      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
-    }
-    public static FibArgs ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
-      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
-    }
-    public static FibArgs ParseDelimitedFrom(global::System.IO.Stream input) {
-      return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
-    }
-    public static FibArgs ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
-      return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
-    }
-    public static FibArgs ParseFrom(pb::ICodedInputStream input) {
-      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
-    }
-    public static FibArgs ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
-      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
-    }
-    private FibArgs MakeReadOnly() {
-      return this;
+    public int CalculateSize() {
+      int size = 0;
+      if (Limit != 0L) {
+        size += 1 + pb::CodedOutputStream.ComputeInt64Size(Limit);
+      }
+      return size;
     }
 
-    public static Builder CreateBuilder() { return new Builder(); }
-    public override Builder ToBuilder() { return CreateBuilder(this); }
-    public override Builder CreateBuilderForType() { return new Builder(); }
-    public static Builder CreateBuilder(FibArgs prototype) {
-      return new Builder(prototype);
+    public void MergeFrom(FibArgs other) {
+      if (other == null) {
+        return;
+      }
+      if (other.Limit != 0L) {
+        Limit = other.Limit;
+      }
     }
 
-    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
-    public sealed partial class Builder : pb::GeneratedBuilder<FibArgs, Builder> {
-      protected override Builder ThisBuilder {
-        get { return this; }
-      }
-      public Builder() {
-        result = DefaultInstance;
-        resultIsReadOnly = true;
-      }
-      internal Builder(FibArgs cloneFrom) {
-        result = cloneFrom;
-        resultIsReadOnly = true;
-      }
-
-      private bool resultIsReadOnly;
-      private FibArgs result;
-
-      private FibArgs PrepareBuilder() {
-        if (resultIsReadOnly) {
-          FibArgs original = result;
-          result = new FibArgs();
-          resultIsReadOnly = false;
-          MergeFrom(original);
-        }
-        return result;
-      }
-
-      public override bool IsInitialized {
-        get { return result.IsInitialized; }
-      }
-
-      protected override FibArgs MessageBeingBuilt {
-        get { return PrepareBuilder(); }
-      }
-
-      public override Builder Clear() {
-        result = DefaultInstance;
-        resultIsReadOnly = true;
-        return this;
-      }
-
-      public override Builder Clone() {
-        if (resultIsReadOnly) {
-          return new Builder(result);
-        } else {
-          return new Builder().MergeFrom(result);
-        }
-      }
-
-      public override pbd::MessageDescriptor DescriptorForType {
-        get { return global::math.FibArgs.Descriptor; }
-      }
-
-      public override FibArgs DefaultInstanceForType {
-        get { return global::math.FibArgs.DefaultInstance; }
-      }
-
-      public override FibArgs BuildPartial() {
-        if (resultIsReadOnly) {
-          return result;
-        }
-        resultIsReadOnly = true;
-        return result.MakeReadOnly();
-      }
-
-      public override Builder MergeFrom(pb::IMessage other) {
-        if (other is FibArgs) {
-          return MergeFrom((FibArgs) other);
-        } else {
-          base.MergeFrom(other);
-          return this;
-        }
-      }
-
-      public override Builder MergeFrom(FibArgs other) {
-        if (other == global::math.FibArgs.DefaultInstance) return this;
-        PrepareBuilder();
-        if (other.HasLimit) {
-          Limit = other.Limit;
-        }
-        this.MergeUnknownFields(other.UnknownFields);
-        return this;
-      }
-
-      public override Builder MergeFrom(pb::ICodedInputStream input) {
-        return MergeFrom(input, pb::ExtensionRegistry.Empty);
-      }
-
-      public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
-        PrepareBuilder();
-        pb::UnknownFieldSet.Builder unknownFields = null;
-        uint tag;
-        string field_name;
-        while (input.ReadTag(out tag, out field_name)) {
-          if(tag == 0 && field_name != null) {
-            int field_ordinal = global::System.Array.BinarySearch(_fibArgsFieldNames, field_name, global::System.StringComparer.Ordinal);
-            if(field_ordinal >= 0)
-              tag = _fibArgsFieldTags[field_ordinal];
-            else {
-              if (unknownFields == null) {
-                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
-              }
-              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);
-              continue;
-            }
-          }
-          switch (tag) {
-            case 0: {
-              throw pb::InvalidProtocolBufferException.InvalidTag();
-            }
-            default: {
-              if (pb::WireFormat.IsEndGroupTag(tag)) {
-                if (unknownFields != null) {
-                  this.UnknownFields = unknownFields.Build();
-                }
-                return this;
-              }
-              if (unknownFields == null) {
-                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
-              }
-              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);
-              break;
-            }
-            case 8: {
-              result.hasLimit = input.ReadInt64(ref result.limit_);
-              break;
-            }
+    public void MergeFrom(pb::CodedInputStream input) {
+      uint tag;
+      while ((tag = input.ReadTag()) != 0) {
+        switch(tag) {
+          default:
+            input.SkipLastField();
+            break;
+          case 8: {
+            Limit = input.ReadInt64();
+            break;
           }
         }
-
-        if (unknownFields != null) {
-          this.UnknownFields = unknownFields.Build();
-        }
-        return this;
-      }
-
-
-      public bool HasLimit {
-        get { return result.hasLimit; }
-      }
-      public long Limit {
-        get { return result.Limit; }
-        set { SetLimit(value); }
-      }
-      public Builder SetLimit(long value) {
-        PrepareBuilder();
-        result.hasLimit = true;
-        result.limit_ = value;
-        return this;
-      }
-      public Builder ClearLimit() {
-        PrepareBuilder();
-        result.hasLimit = false;
-        result.limit_ = 0L;
-        return this;
       }
     }
-    static FibArgs() {
-      object.ReferenceEquals(global::math.Proto.Math.Descriptor, null);
-    }
+
   }
 
   [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
-  public sealed partial class Num : pb::GeneratedMessage<Num, Num.Builder> {
-    private Num() { }
-    private static readonly Num defaultInstance = new Num().MakeReadOnly();
-    private static readonly string[] _numFieldNames = new string[] { "num" };
-    private static readonly uint[] _numFieldTags = new uint[] { 8 };
-    public static Num DefaultInstance {
-      get { return defaultInstance; }
+  public sealed partial class Num : pb::IMessage<Num> {
+    private static readonly pb::MessageParser<Num> _parser = new pb::MessageParser<Num>(() => new Num());
+    public static pb::MessageParser<Num> Parser { get { return _parser; } }
+
+    public static pbr::MessageDescriptor Descriptor {
+      get { return global::Math.Proto.Math.Descriptor.MessageTypes[3]; }
     }
 
-    public override Num DefaultInstanceForType {
-      get { return DefaultInstance; }
+    pbr::MessageDescriptor pb::IMessage.Descriptor {
+      get { return Descriptor; }
     }
 
-    protected override Num ThisMessage {
-      get { return this; }
+    public Num() {
+      OnConstruction();
     }
 
-    public static pbd::MessageDescriptor Descriptor {
-      get { return global::math.Proto.Math.internal__static_math_Num__Descriptor; }
+    partial void OnConstruction();
+
+    public Num(Num other) : this() {
+      num_ = other.num_;
     }
 
-    protected override pb::FieldAccess.FieldAccessorTable<Num, Num.Builder> InternalFieldAccessors {
-      get { return global::math.Proto.Math.internal__static_math_Num__FieldAccessorTable; }
+    public Num Clone() {
+      return new Num(this);
     }
 
     public const int Num_FieldNumber = 1;
-    private bool hasNum_;
     private long num_;
-    public bool HasNum_ {
-      get { return hasNum_; }
-    }
     public long Num_ {
       get { return num_; }
+      set {
+        num_ = value;
+      }
     }
 
-    public override bool IsInitialized {
-      get {
+    public override bool Equals(object other) {
+      return Equals(other as Num);
+    }
+
+    public bool Equals(Num other) {
+      if (ReferenceEquals(other, null)) {
+        return false;
+      }
+      if (ReferenceEquals(other, this)) {
         return true;
       }
+      if (Num_ != other.Num_) return false;
+      return true;
     }
 
-    public override void WriteTo(pb::ICodedOutputStream output) {
-      int size = SerializedSize;
-      string[] field_names = _numFieldNames;
-      if (hasNum_) {
-        output.WriteInt64(1, field_names[0], Num_);
-      }
-      UnknownFields.WriteTo(output);
+    public override int GetHashCode() {
+      int hash = 1;
+      if (Num_ != 0L) hash ^= Num_.GetHashCode();
+      return hash;
     }
 
-    private int memoizedSerializedSize = -1;
-    public override int SerializedSize {
-      get {
-        int size = memoizedSerializedSize;
-        if (size != -1) return size;
+    public override string ToString() {
+      return pb::JsonFormatter.Default.Format(this);
+    }
 
-        size = 0;
-        if (hasNum_) {
-          size += pb::CodedOutputStream.ComputeInt64Size(1, Num_);
-        }
-        size += UnknownFields.SerializedSize;
-        memoizedSerializedSize = size;
-        return size;
+    public void WriteTo(pb::CodedOutputStream output) {
+      if (Num_ != 0L) {
+        output.WriteRawTag(8);
+        output.WriteInt64(Num_);
       }
     }
 
-    public static Num ParseFrom(pb::ByteString data) {
-      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
-    }
-    public static Num ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
-      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
-    }
-    public static Num ParseFrom(byte[] data) {
-      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
-    }
-    public static Num ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
-      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
-    }
-    public static Num ParseFrom(global::System.IO.Stream input) {
-      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
-    }
-    public static Num ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
-      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
-    }
-    public static Num ParseDelimitedFrom(global::System.IO.Stream input) {
-      return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
-    }
-    public static Num ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
-      return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
-    }
-    public static Num ParseFrom(pb::ICodedInputStream input) {
-      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
-    }
-    public static Num ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
-      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
-    }
-    private Num MakeReadOnly() {
-      return this;
+    public int CalculateSize() {
+      int size = 0;
+      if (Num_ != 0L) {
+        size += 1 + pb::CodedOutputStream.ComputeInt64Size(Num_);
+      }
+      return size;
     }
 
-    public static Builder CreateBuilder() { return new Builder(); }
-    public override Builder ToBuilder() { return CreateBuilder(this); }
-    public override Builder CreateBuilderForType() { return new Builder(); }
-    public static Builder CreateBuilder(Num prototype) {
-      return new Builder(prototype);
+    public void MergeFrom(Num other) {
+      if (other == null) {
+        return;
+      }
+      if (other.Num_ != 0L) {
+        Num_ = other.Num_;
+      }
     }
 
-    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
-    public sealed partial class Builder : pb::GeneratedBuilder<Num, Builder> {
-      protected override Builder ThisBuilder {
-        get { return this; }
-      }
-      public Builder() {
-        result = DefaultInstance;
-        resultIsReadOnly = true;
-      }
-      internal Builder(Num cloneFrom) {
-        result = cloneFrom;
-        resultIsReadOnly = true;
-      }
-
-      private bool resultIsReadOnly;
-      private Num result;
-
-      private Num PrepareBuilder() {
-        if (resultIsReadOnly) {
-          Num original = result;
-          result = new Num();
-          resultIsReadOnly = false;
-          MergeFrom(original);
-        }
-        return result;
-      }
-
-      public override bool IsInitialized {
-        get { return result.IsInitialized; }
-      }
-
-      protected override Num MessageBeingBuilt {
-        get { return PrepareBuilder(); }
-      }
-
-      public override Builder Clear() {
-        result = DefaultInstance;
-        resultIsReadOnly = true;
-        return this;
-      }
-
-      public override Builder Clone() {
-        if (resultIsReadOnly) {
-          return new Builder(result);
-        } else {
-          return new Builder().MergeFrom(result);
-        }
-      }
-
-      public override pbd::MessageDescriptor DescriptorForType {
-        get { return global::math.Num.Descriptor; }
-      }
-
-      public override Num DefaultInstanceForType {
-        get { return global::math.Num.DefaultInstance; }
-      }
-
-      public override Num BuildPartial() {
-        if (resultIsReadOnly) {
-          return result;
-        }
-        resultIsReadOnly = true;
-        return result.MakeReadOnly();
-      }
-
-      public override Builder MergeFrom(pb::IMessage other) {
-        if (other is Num) {
-          return MergeFrom((Num) other);
-        } else {
-          base.MergeFrom(other);
-          return this;
-        }
-      }
-
-      public override Builder MergeFrom(Num other) {
-        if (other == global::math.Num.DefaultInstance) return this;
-        PrepareBuilder();
-        if (other.HasNum_) {
-          Num_ = other.Num_;
-        }
-        this.MergeUnknownFields(other.UnknownFields);
-        return this;
-      }
-
-      public override Builder MergeFrom(pb::ICodedInputStream input) {
-        return MergeFrom(input, pb::ExtensionRegistry.Empty);
-      }
-
-      public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
-        PrepareBuilder();
-        pb::UnknownFieldSet.Builder unknownFields = null;
-        uint tag;
-        string field_name;
-        while (input.ReadTag(out tag, out field_name)) {
-          if(tag == 0 && field_name != null) {
-            int field_ordinal = global::System.Array.BinarySearch(_numFieldNames, field_name, global::System.StringComparer.Ordinal);
-            if(field_ordinal >= 0)
-              tag = _numFieldTags[field_ordinal];
-            else {
-              if (unknownFields == null) {
-                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
-              }
-              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);
-              continue;
-            }
-          }
-          switch (tag) {
-            case 0: {
-              throw pb::InvalidProtocolBufferException.InvalidTag();
-            }
-            default: {
-              if (pb::WireFormat.IsEndGroupTag(tag)) {
-                if (unknownFields != null) {
-                  this.UnknownFields = unknownFields.Build();
-                }
-                return this;
-              }
-              if (unknownFields == null) {
-                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
-              }
-              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);
-              break;
-            }
-            case 8: {
-              result.hasNum_ = input.ReadInt64(ref result.num_);
-              break;
-            }
+    public void MergeFrom(pb::CodedInputStream input) {
+      uint tag;
+      while ((tag = input.ReadTag()) != 0) {
+        switch(tag) {
+          default:
+            input.SkipLastField();
+            break;
+          case 8: {
+            Num_ = input.ReadInt64();
+            break;
           }
         }
-
-        if (unknownFields != null) {
-          this.UnknownFields = unknownFields.Build();
-        }
-        return this;
-      }
-
-
-      public bool HasNum_ {
-        get { return result.hasNum_; }
-      }
-      public long Num_ {
-        get { return result.Num_; }
-        set { SetNum_(value); }
-      }
-      public Builder SetNum_(long value) {
-        PrepareBuilder();
-        result.hasNum_ = true;
-        result.num_ = value;
-        return this;
-      }
-      public Builder ClearNum_() {
-        PrepareBuilder();
-        result.hasNum_ = false;
-        result.num_ = 0L;
-        return this;
       }
     }
-    static Num() {
-      object.ReferenceEquals(global::math.Proto.Math.Descriptor, null);
-    }
+
   }
 
   [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
-  public sealed partial class FibReply : pb::GeneratedMessage<FibReply, FibReply.Builder> {
-    private FibReply() { }
-    private static readonly FibReply defaultInstance = new FibReply().MakeReadOnly();
-    private static readonly string[] _fibReplyFieldNames = new string[] { "count" };
-    private static readonly uint[] _fibReplyFieldTags = new uint[] { 8 };
-    public static FibReply DefaultInstance {
-      get { return defaultInstance; }
+  public sealed partial class FibReply : pb::IMessage<FibReply> {
+    private static readonly pb::MessageParser<FibReply> _parser = new pb::MessageParser<FibReply>(() => new FibReply());
+    public static pb::MessageParser<FibReply> Parser { get { return _parser; } }
+
+    public static pbr::MessageDescriptor Descriptor {
+      get { return global::Math.Proto.Math.Descriptor.MessageTypes[4]; }
     }
 
-    public override FibReply DefaultInstanceForType {
-      get { return DefaultInstance; }
+    pbr::MessageDescriptor pb::IMessage.Descriptor {
+      get { return Descriptor; }
     }
 
-    protected override FibReply ThisMessage {
-      get { return this; }
+    public FibReply() {
+      OnConstruction();
     }
 
-    public static pbd::MessageDescriptor Descriptor {
-      get { return global::math.Proto.Math.internal__static_math_FibReply__Descriptor; }
+    partial void OnConstruction();
+
+    public FibReply(FibReply other) : this() {
+      count_ = other.count_;
     }
 
-    protected override pb::FieldAccess.FieldAccessorTable<FibReply, FibReply.Builder> InternalFieldAccessors {
-      get { return global::math.Proto.Math.internal__static_math_FibReply__FieldAccessorTable; }
+    public FibReply Clone() {
+      return new FibReply(this);
     }
 
     public const int CountFieldNumber = 1;
-    private bool hasCount;
     private long count_;
-    public bool HasCount {
-      get { return hasCount; }
-    }
     public long Count {
       get { return count_; }
+      set {
+        count_ = value;
+      }
     }
 
-    public override bool IsInitialized {
-      get {
+    public override bool Equals(object other) {
+      return Equals(other as FibReply);
+    }
+
+    public bool Equals(FibReply other) {
+      if (ReferenceEquals(other, null)) {
+        return false;
+      }
+      if (ReferenceEquals(other, this)) {
         return true;
       }
+      if (Count != other.Count) return false;
+      return true;
     }
 
-    public override void WriteTo(pb::ICodedOutputStream output) {
-      int size = SerializedSize;
-      string[] field_names = _fibReplyFieldNames;
-      if (hasCount) {
-        output.WriteInt64(1, field_names[0], Count);
-      }
-      UnknownFields.WriteTo(output);
+    public override int GetHashCode() {
+      int hash = 1;
+      if (Count != 0L) hash ^= Count.GetHashCode();
+      return hash;
     }
 
-    private int memoizedSerializedSize = -1;
-    public override int SerializedSize {
-      get {
-        int size = memoizedSerializedSize;
-        if (size != -1) return size;
+    public override string ToString() {
+      return pb::JsonFormatter.Default.Format(this);
+    }
 
-        size = 0;
-        if (hasCount) {
-          size += pb::CodedOutputStream.ComputeInt64Size(1, Count);
-        }
-        size += UnknownFields.SerializedSize;
-        memoizedSerializedSize = size;
-        return size;
+    public void WriteTo(pb::CodedOutputStream output) {
+      if (Count != 0L) {
+        output.WriteRawTag(8);
+        output.WriteInt64(Count);
       }
     }
 
-    public static FibReply ParseFrom(pb::ByteString data) {
-      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
-    }
-    public static FibReply ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
-      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
-    }
-    public static FibReply ParseFrom(byte[] data) {
-      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
-    }
-    public static FibReply ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
-      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
-    }
-    public static FibReply ParseFrom(global::System.IO.Stream input) {
-      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
-    }
-    public static FibReply ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
-      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
-    }
-    public static FibReply ParseDelimitedFrom(global::System.IO.Stream input) {
-      return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
-    }
-    public static FibReply ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
-      return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
-    }
-    public static FibReply ParseFrom(pb::ICodedInputStream input) {
-      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
-    }
-    public static FibReply ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
-      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
-    }
-    private FibReply MakeReadOnly() {
-      return this;
+    public int CalculateSize() {
+      int size = 0;
+      if (Count != 0L) {
+        size += 1 + pb::CodedOutputStream.ComputeInt64Size(Count);
+      }
+      return size;
     }
 
-    public static Builder CreateBuilder() { return new Builder(); }
-    public override Builder ToBuilder() { return CreateBuilder(this); }
-    public override Builder CreateBuilderForType() { return new Builder(); }
-    public static Builder CreateBuilder(FibReply prototype) {
-      return new Builder(prototype);
+    public void MergeFrom(FibReply other) {
+      if (other == null) {
+        return;
+      }
+      if (other.Count != 0L) {
+        Count = other.Count;
+      }
     }
 
-    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
-    public sealed partial class Builder : pb::GeneratedBuilder<FibReply, Builder> {
-      protected override Builder ThisBuilder {
-        get { return this; }
-      }
-      public Builder() {
-        result = DefaultInstance;
-        resultIsReadOnly = true;
-      }
-      internal Builder(FibReply cloneFrom) {
-        result = cloneFrom;
-        resultIsReadOnly = true;
-      }
-
-      private bool resultIsReadOnly;
-      private FibReply result;
-
-      private FibReply PrepareBuilder() {
-        if (resultIsReadOnly) {
-          FibReply original = result;
-          result = new FibReply();
-          resultIsReadOnly = false;
-          MergeFrom(original);
-        }
-        return result;
-      }
-
-      public override bool IsInitialized {
-        get { return result.IsInitialized; }
-      }
-
-      protected override FibReply MessageBeingBuilt {
-        get { return PrepareBuilder(); }
-      }
-
-      public override Builder Clear() {
-        result = DefaultInstance;
-        resultIsReadOnly = true;
-        return this;
-      }
-
-      public override Builder Clone() {
-        if (resultIsReadOnly) {
-          return new Builder(result);
-        } else {
-          return new Builder().MergeFrom(result);
-        }
-      }
-
-      public override pbd::MessageDescriptor DescriptorForType {
-        get { return global::math.FibReply.Descriptor; }
-      }
-
-      public override FibReply DefaultInstanceForType {
-        get { return global::math.FibReply.DefaultInstance; }
-      }
-
-      public override FibReply BuildPartial() {
-        if (resultIsReadOnly) {
-          return result;
-        }
-        resultIsReadOnly = true;
-        return result.MakeReadOnly();
-      }
-
-      public override Builder MergeFrom(pb::IMessage other) {
-        if (other is FibReply) {
-          return MergeFrom((FibReply) other);
-        } else {
-          base.MergeFrom(other);
-          return this;
-        }
-      }
-
-      public override Builder MergeFrom(FibReply other) {
-        if (other == global::math.FibReply.DefaultInstance) return this;
-        PrepareBuilder();
-        if (other.HasCount) {
-          Count = other.Count;
-        }
-        this.MergeUnknownFields(other.UnknownFields);
-        return this;
-      }
-
-      public override Builder MergeFrom(pb::ICodedInputStream input) {
-        return MergeFrom(input, pb::ExtensionRegistry.Empty);
-      }
-
-      public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
-        PrepareBuilder();
-        pb::UnknownFieldSet.Builder unknownFields = null;
-        uint tag;
-        string field_name;
-        while (input.ReadTag(out tag, out field_name)) {
-          if(tag == 0 && field_name != null) {
-            int field_ordinal = global::System.Array.BinarySearch(_fibReplyFieldNames, field_name, global::System.StringComparer.Ordinal);
-            if(field_ordinal >= 0)
-              tag = _fibReplyFieldTags[field_ordinal];
-            else {
-              if (unknownFields == null) {
-                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
-              }
-              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);
-              continue;
-            }
-          }
-          switch (tag) {
-            case 0: {
-              throw pb::InvalidProtocolBufferException.InvalidTag();
-            }
-            default: {
-              if (pb::WireFormat.IsEndGroupTag(tag)) {
-                if (unknownFields != null) {
-                  this.UnknownFields = unknownFields.Build();
-                }
-                return this;
-              }
-              if (unknownFields == null) {
-                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
-              }
-              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);
-              break;
-            }
-            case 8: {
-              result.hasCount = input.ReadInt64(ref result.count_);
-              break;
-            }
+    public void MergeFrom(pb::CodedInputStream input) {
+      uint tag;
+      while ((tag = input.ReadTag()) != 0) {
+        switch(tag) {
+          default:
+            input.SkipLastField();
+            break;
+          case 8: {
+            Count = input.ReadInt64();
+            break;
           }
         }
-
-        if (unknownFields != null) {
-          this.UnknownFields = unknownFields.Build();
-        }
-        return this;
-      }
-
-
-      public bool HasCount {
-        get { return result.hasCount; }
-      }
-      public long Count {
-        get { return result.Count; }
-        set { SetCount(value); }
-      }
-      public Builder SetCount(long value) {
-        PrepareBuilder();
-        result.hasCount = true;
-        result.count_ = value;
-        return this;
-      }
-      public Builder ClearCount() {
-        PrepareBuilder();
-        result.hasCount = false;
-        result.count_ = 0L;
-        return this;
       }
     }
-    static FibReply() {
-      object.ReferenceEquals(global::math.Proto.Math.Descriptor, null);
-    }
+
   }
 
   #endregion
 
-  #region Services
-  /*
-  * Service generation is now disabled by default, use the following option to enable:
-  * option (google.protobuf.csharp_file_options).service_generator_type = GENERIC;
-  */
-  #endregion
-
 }
 
 #endregion Designer generated code
diff --git a/src/csharp/Grpc.Examples/MathExamples.cs b/src/csharp/Grpc.Examples/MathExamples.cs
index dc1bf43..8009ccb 100644
--- a/src/csharp/Grpc.Examples/MathExamples.cs
+++ b/src/csharp/Grpc.Examples/MathExamples.cs
@@ -34,25 +34,25 @@
 using System.Threading.Tasks;
 using Grpc.Core.Utils;
 
-namespace math
+namespace Math
 {
     public static class MathExamples
     {
         public static void DivExample(Math.IMathClient client)
         {
-            DivReply result = client.Div(new DivArgs.Builder { Dividend = 10, Divisor = 3 }.Build());
+            DivReply result = client.Div(new DivArgs { Dividend = 10, Divisor = 3 });
             Console.WriteLine("Div Result: " + result);
         }
 
         public static async Task DivAsyncExample(Math.IMathClient client)
         {
-            DivReply result = await client.DivAsync(new DivArgs.Builder { Dividend = 4, Divisor = 5 }.Build());
+            DivReply result = await client.DivAsync(new DivArgs { Dividend = 4, Divisor = 5 });
             Console.WriteLine("DivAsync Result: " + result);
         }
 
         public static async Task FibExample(Math.IMathClient client)
         {
-            using (var call = client.Fib(new FibArgs.Builder { Limit = 5 }.Build()))
+            using (var call = client.Fib(new FibArgs { Limit = 5 }))
             {
                 List<Num> result = await call.ResponseStream.ToListAsync();
                 Console.WriteLine("Fib Result: " + string.Join("|", result));
@@ -63,9 +63,9 @@
         {
             var numbers = new List<Num>
             {
-                new Num.Builder { Num_ = 1 }.Build(),
-                new Num.Builder { Num_ = 2 }.Build(),
-                new Num.Builder { Num_ = 3 }.Build()
+                new Num { Num_ = 1 },
+                new Num { Num_ = 2 },
+                new Num { Num_ = 3 }
             };
 
             using (var call = client.Sum())
@@ -79,9 +79,9 @@
         {
             var divArgsList = new List<DivArgs>
             {
-                new DivArgs.Builder { Dividend = 10, Divisor = 3 }.Build(),
-                new DivArgs.Builder { Dividend = 100, Divisor = 21 }.Build(),
-                new DivArgs.Builder { Dividend = 7, Divisor = 2 }.Build()
+                new DivArgs { Dividend = 10, Divisor = 3 },
+                new DivArgs { Dividend = 100, Divisor = 21 },
+                new DivArgs { Dividend = 7, Divisor = 2 }
             };
             using (var call = client.DivMany())
             { 
@@ -94,9 +94,9 @@
         {
             var numbers = new List<Num>
             {
-                new Num.Builder { Num_ = 1 }.Build(), 
-                new Num.Builder { Num_ = 2 }.Build(),
-                new Num.Builder { Num_ = 3 }.Build()
+                new Num { Num_ = 1 }, 
+                new Num { Num_ = 2 },
+                new Num { Num_ = 3 }
             };
 
             Num sum;
@@ -106,7 +106,7 @@
                 sum = await sumCall.ResponseAsync;
             }
 
-            DivReply result = await client.DivAsync(new DivArgs.Builder { Dividend = sum.Num_, Divisor = numbers.Count }.Build());
+            DivReply result = await client.DivAsync(new DivArgs { Dividend = sum.Num_, Divisor = numbers.Count });
             Console.WriteLine("Avg Result: " + result);
         }
     }
diff --git a/src/csharp/Grpc.Examples/MathGrpc.cs b/src/csharp/Grpc.Examples/MathGrpc.cs
index 4941ff3..175d110 100644
--- a/src/csharp/Grpc.Examples/MathGrpc.cs
+++ b/src/csharp/Grpc.Examples/MathGrpc.cs
@@ -7,66 +7,72 @@
 using System.Threading.Tasks;
 using Grpc.Core;
 
-namespace math {
+namespace Math {
   public static class Math
   {
     static readonly string __ServiceName = "math.Math";
 
-    static readonly Marshaller<global::math.DivArgs> __Marshaller_DivArgs = Marshallers.Create((arg) => arg.ToByteArray(), global::math.DivArgs.ParseFrom);
-    static readonly Marshaller<global::math.DivReply> __Marshaller_DivReply = Marshallers.Create((arg) => arg.ToByteArray(), global::math.DivReply.ParseFrom);
-    static readonly Marshaller<global::math.FibArgs> __Marshaller_FibArgs = Marshallers.Create((arg) => arg.ToByteArray(), global::math.FibArgs.ParseFrom);
-    static readonly Marshaller<global::math.Num> __Marshaller_Num = Marshallers.Create((arg) => arg.ToByteArray(), global::math.Num.ParseFrom);
+    static readonly Marshaller<global::Math.DivArgs> __Marshaller_DivArgs = Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Math.DivArgs.Parser.ParseFrom);
+    static readonly Marshaller<global::Math.DivReply> __Marshaller_DivReply = Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Math.DivReply.Parser.ParseFrom);
+    static readonly Marshaller<global::Math.FibArgs> __Marshaller_FibArgs = Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Math.FibArgs.Parser.ParseFrom);
+    static readonly Marshaller<global::Math.Num> __Marshaller_Num = Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Math.Num.Parser.ParseFrom);
 
-    static readonly Method<global::math.DivArgs, global::math.DivReply> __Method_Div = new Method<global::math.DivArgs, global::math.DivReply>(
+    static readonly Method<global::Math.DivArgs, global::Math.DivReply> __Method_Div = new Method<global::Math.DivArgs, global::Math.DivReply>(
         MethodType.Unary,
         __ServiceName,
         "Div",
         __Marshaller_DivArgs,
         __Marshaller_DivReply);
 
-    static readonly Method<global::math.DivArgs, global::math.DivReply> __Method_DivMany = new Method<global::math.DivArgs, global::math.DivReply>(
+    static readonly Method<global::Math.DivArgs, global::Math.DivReply> __Method_DivMany = new Method<global::Math.DivArgs, global::Math.DivReply>(
         MethodType.DuplexStreaming,
         __ServiceName,
         "DivMany",
         __Marshaller_DivArgs,
         __Marshaller_DivReply);
 
-    static readonly Method<global::math.FibArgs, global::math.Num> __Method_Fib = new Method<global::math.FibArgs, global::math.Num>(
+    static readonly Method<global::Math.FibArgs, global::Math.Num> __Method_Fib = new Method<global::Math.FibArgs, global::Math.Num>(
         MethodType.ServerStreaming,
         __ServiceName,
         "Fib",
         __Marshaller_FibArgs,
         __Marshaller_Num);
 
-    static readonly Method<global::math.Num, global::math.Num> __Method_Sum = new Method<global::math.Num, global::math.Num>(
+    static readonly Method<global::Math.Num, global::Math.Num> __Method_Sum = new Method<global::Math.Num, global::Math.Num>(
         MethodType.ClientStreaming,
         __ServiceName,
         "Sum",
         __Marshaller_Num,
         __Marshaller_Num);
 
+    // service descriptor
+    public static global::Google.Protobuf.Reflection.ServiceDescriptor Descriptor
+    {
+      get { return global::Math.Proto.Math.Descriptor.Services[0]; }
+    }
+
     // client interface
     public interface IMathClient
     {
-      global::math.DivReply Div(global::math.DivArgs request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
-      global::math.DivReply Div(global::math.DivArgs request, CallOptions options);
-      AsyncUnaryCall<global::math.DivReply> DivAsync(global::math.DivArgs request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
-      AsyncUnaryCall<global::math.DivReply> DivAsync(global::math.DivArgs request, CallOptions options);
-      AsyncDuplexStreamingCall<global::math.DivArgs, global::math.DivReply> DivMany(Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
-      AsyncDuplexStreamingCall<global::math.DivArgs, global::math.DivReply> DivMany(CallOptions options);
-      AsyncServerStreamingCall<global::math.Num> Fib(global::math.FibArgs request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
-      AsyncServerStreamingCall<global::math.Num> Fib(global::math.FibArgs request, CallOptions options);
-      AsyncClientStreamingCall<global::math.Num, global::math.Num> Sum(Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
-      AsyncClientStreamingCall<global::math.Num, global::math.Num> Sum(CallOptions options);
+      global::Math.DivReply Div(global::Math.DivArgs request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
+      global::Math.DivReply Div(global::Math.DivArgs request, CallOptions options);
+      AsyncUnaryCall<global::Math.DivReply> DivAsync(global::Math.DivArgs request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
+      AsyncUnaryCall<global::Math.DivReply> DivAsync(global::Math.DivArgs request, CallOptions options);
+      AsyncDuplexStreamingCall<global::Math.DivArgs, global::Math.DivReply> DivMany(Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
+      AsyncDuplexStreamingCall<global::Math.DivArgs, global::Math.DivReply> DivMany(CallOptions options);
+      AsyncServerStreamingCall<global::Math.Num> Fib(global::Math.FibArgs request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
+      AsyncServerStreamingCall<global::Math.Num> Fib(global::Math.FibArgs request, CallOptions options);
+      AsyncClientStreamingCall<global::Math.Num, global::Math.Num> Sum(Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
+      AsyncClientStreamingCall<global::Math.Num, global::Math.Num> Sum(CallOptions options);
     }
 
     // server-side interface
     public interface IMath
     {
-      Task<global::math.DivReply> Div(global::math.DivArgs request, ServerCallContext context);
-      Task DivMany(IAsyncStreamReader<global::math.DivArgs> requestStream, IServerStreamWriter<global::math.DivReply> responseStream, ServerCallContext context);
-      Task Fib(global::math.FibArgs request, IServerStreamWriter<global::math.Num> responseStream, ServerCallContext context);
-      Task<global::math.Num> Sum(IAsyncStreamReader<global::math.Num> requestStream, ServerCallContext context);
+      Task<global::Math.DivReply> Div(global::Math.DivArgs request, ServerCallContext context);
+      Task DivMany(IAsyncStreamReader<global::Math.DivArgs> requestStream, IServerStreamWriter<global::Math.DivReply> responseStream, ServerCallContext context);
+      Task Fib(global::Math.FibArgs request, IServerStreamWriter<global::Math.Num> responseStream, ServerCallContext context);
+      Task<global::Math.Num> Sum(IAsyncStreamReader<global::Math.Num> requestStream, ServerCallContext context);
     }
 
     // client stub
@@ -75,52 +81,52 @@
       public MathClient(Channel channel) : base(channel)
       {
       }
-      public global::math.DivReply Div(global::math.DivArgs request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+      public global::Math.DivReply Div(global::Math.DivArgs request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
         var call = CreateCall(__Method_Div, new CallOptions(headers, deadline, cancellationToken));
         return Calls.BlockingUnaryCall(call, request);
       }
-      public global::math.DivReply Div(global::math.DivArgs request, CallOptions options)
+      public global::Math.DivReply Div(global::Math.DivArgs request, CallOptions options)
       {
         var call = CreateCall(__Method_Div, options);
         return Calls.BlockingUnaryCall(call, request);
       }
-      public AsyncUnaryCall<global::math.DivReply> DivAsync(global::math.DivArgs request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+      public AsyncUnaryCall<global::Math.DivReply> DivAsync(global::Math.DivArgs request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
         var call = CreateCall(__Method_Div, new CallOptions(headers, deadline, cancellationToken));
         return Calls.AsyncUnaryCall(call, request);
       }
-      public AsyncUnaryCall<global::math.DivReply> DivAsync(global::math.DivArgs request, CallOptions options)
+      public AsyncUnaryCall<global::Math.DivReply> DivAsync(global::Math.DivArgs request, CallOptions options)
       {
         var call = CreateCall(__Method_Div, options);
         return Calls.AsyncUnaryCall(call, request);
       }
-      public AsyncDuplexStreamingCall<global::math.DivArgs, global::math.DivReply> DivMany(Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+      public AsyncDuplexStreamingCall<global::Math.DivArgs, global::Math.DivReply> DivMany(Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
         var call = CreateCall(__Method_DivMany, new CallOptions(headers, deadline, cancellationToken));
         return Calls.AsyncDuplexStreamingCall(call);
       }
-      public AsyncDuplexStreamingCall<global::math.DivArgs, global::math.DivReply> DivMany(CallOptions options)
+      public AsyncDuplexStreamingCall<global::Math.DivArgs, global::Math.DivReply> DivMany(CallOptions options)
       {
         var call = CreateCall(__Method_DivMany, options);
         return Calls.AsyncDuplexStreamingCall(call);
       }
-      public AsyncServerStreamingCall<global::math.Num> Fib(global::math.FibArgs request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+      public AsyncServerStreamingCall<global::Math.Num> Fib(global::Math.FibArgs request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
         var call = CreateCall(__Method_Fib, new CallOptions(headers, deadline, cancellationToken));
         return Calls.AsyncServerStreamingCall(call, request);
       }
-      public AsyncServerStreamingCall<global::math.Num> Fib(global::math.FibArgs request, CallOptions options)
+      public AsyncServerStreamingCall<global::Math.Num> Fib(global::Math.FibArgs request, CallOptions options)
       {
         var call = CreateCall(__Method_Fib, options);
         return Calls.AsyncServerStreamingCall(call, request);
       }
-      public AsyncClientStreamingCall<global::math.Num, global::math.Num> Sum(Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+      public AsyncClientStreamingCall<global::Math.Num, global::Math.Num> Sum(Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
         var call = CreateCall(__Method_Sum, new CallOptions(headers, deadline, cancellationToken));
         return Calls.AsyncClientStreamingCall(call);
       }
-      public AsyncClientStreamingCall<global::math.Num, global::math.Num> Sum(CallOptions options)
+      public AsyncClientStreamingCall<global::Math.Num, global::Math.Num> Sum(CallOptions options)
       {
         var call = CreateCall(__Method_Sum, options);
         return Calls.AsyncClientStreamingCall(call);
diff --git a/src/csharp/Grpc.Examples/MathServiceImpl.cs b/src/csharp/Grpc.Examples/MathServiceImpl.cs
index 7b26846..71dc655 100644
--- a/src/csharp/Grpc.Examples/MathServiceImpl.cs
+++ b/src/csharp/Grpc.Examples/MathServiceImpl.cs
@@ -38,7 +38,7 @@
 using Grpc.Core;
 using Grpc.Core.Utils;
 
-namespace math
+namespace Math
 {
     /// <summary>
     /// Implementation of MathService server
@@ -79,7 +79,7 @@
             {
                 sum += num.Num_;
             });
-            return Num.CreateBuilder().SetNum_(sum).Build();
+            return new Num { Num_ = sum };
         }
 
         public async Task DivMany(IAsyncStreamReader<DivArgs> requestStream, IServerStreamWriter<DivReply> responseStream, ServerCallContext context)
@@ -91,13 +91,13 @@
         {
             long quotient = args.Dividend / args.Divisor;
             long remainder = args.Dividend % args.Divisor;
-            return new DivReply.Builder { Quotient = quotient, Remainder = remainder }.Build();
+            return new DivReply { Quotient = quotient, Remainder = remainder };
         }
 
         static IEnumerable<Num> FibInternal(long n)
         {
             long a = 1;
-            yield return new Num.Builder { Num_ = a }.Build();
+            yield return new Num { Num_ = a };
 
             long b = 1;
             for (long i = 0; i < n - 1; i++)
@@ -105,7 +105,7 @@
                 long temp = a;
                 a = b;
                 b = temp + b;
-                yield return new Num.Builder { Num_ = a }.Build();
+                yield return new Num { Num_ = a };
             }
         }        
     }
diff --git a/src/csharp/Grpc.Examples/packages.config b/src/csharp/Grpc.Examples/packages.config
index 4c8d60f..adf8da2 100644
--- a/src/csharp/Grpc.Examples/packages.config
+++ b/src/csharp/Grpc.Examples/packages.config
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <packages>
-  <package id="Google.ProtocolBuffers" version="2.4.1.521" targetFramework="net45" />
+  <package id="Google.Protobuf" version="3.0.0-alpha4" targetFramework="net45" />
   <package id="Ix-Async" version="1.2.3" targetFramework="net45" />
   <package id="NUnit" version="2.6.4" targetFramework="net45" />
 </packages>
\ No newline at end of file
diff --git a/src/csharp/Grpc.Examples/proto/math.proto b/src/csharp/Grpc.Examples/proto/math.proto
index 5485d58..311e148 100644
--- a/src/csharp/Grpc.Examples/proto/math.proto
+++ b/src/csharp/Grpc.Examples/proto/math.proto
@@ -28,30 +28,30 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-syntax = "proto2";
+syntax = "proto3";
 
 package math;
 
 message DivArgs {
-  optional int64 dividend = 1;
-  optional int64 divisor = 2;
+  int64 dividend = 1;
+  int64 divisor = 2;
 }
 
 message DivReply {
-  optional int64 quotient = 1;
-  optional int64 remainder = 2;
+  int64 quotient = 1;
+  int64 remainder = 2;
 }
 
 message FibArgs {
-  optional int64 limit = 1;
+  int64 limit = 1;
 }
 
 message Num {
-  optional int64 num = 1;
+  int64 num = 1;
 }
 
 message FibReply {
-  optional int64 count = 1;
+  int64 count = 1;
 }
 
 service Math {
diff --git a/src/csharp/Grpc.HealthCheck.Tests/Grpc.HealthCheck.Tests.csproj b/src/csharp/Grpc.HealthCheck.Tests/Grpc.HealthCheck.Tests.csproj
index c922ddf..396dc43 100644
--- a/src/csharp/Grpc.HealthCheck.Tests/Grpc.HealthCheck.Tests.csproj
+++ b/src/csharp/Grpc.HealthCheck.Tests/Grpc.HealthCheck.Tests.csproj
@@ -37,11 +37,9 @@
     <AssemblyOriginatorKeyFile>C:\keys\Grpc.snk</AssemblyOriginatorKeyFile>
   </PropertyGroup>
   <ItemGroup>
-    <Reference Include="Google.ProtocolBuffers">
-      <HintPath>..\packages\Google.ProtocolBuffers.2.4.1.555\lib\net40\Google.ProtocolBuffers.dll</HintPath>
-    </Reference>
-    <Reference Include="Google.ProtocolBuffers.Serialization">
-      <HintPath>..\packages\Google.ProtocolBuffers.2.4.1.555\lib\net40\Google.ProtocolBuffers.Serialization.dll</HintPath>
+    <Reference Include="Google.Protobuf, Version=3.0.0.0, Culture=neutral, PublicKeyToken=a7d26565bac4d604, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\packages\Google.Protobuf.3.0.0-alpha4\lib\portable-net45+netcore45+wpa81+wp8\Google.Protobuf.dll</HintPath>
     </Reference>
     <Reference Include="nunit.framework">
       <HintPath>..\packages\NUnit.2.6.4\lib\nunit.framework.dll</HintPath>
diff --git a/src/csharp/Grpc.HealthCheck.Tests/HealthClientServerTest.cs b/src/csharp/Grpc.HealthCheck.Tests/HealthClientServerTest.cs
index 80c35fb..95f742c 100644
--- a/src/csharp/Grpc.HealthCheck.Tests/HealthClientServerTest.cs
+++ b/src/csharp/Grpc.HealthCheck.Tests/HealthClientServerTest.cs
@@ -81,14 +81,14 @@
         {
             serviceImpl.SetStatus("", "", HealthCheckResponse.Types.ServingStatus.SERVING);
 
-            var response = client.Check(HealthCheckRequest.CreateBuilder().SetHost("").SetService("").Build());
+            var response = client.Check(new HealthCheckRequest { Host = "", Service = "" });
             Assert.AreEqual(HealthCheckResponse.Types.ServingStatus.SERVING, response.Status);
         }
 
         [Test]
         public void ServiceDoesntExist()
         {
-            Assert.Throws(Is.TypeOf(typeof(RpcException)).And.Property("Status").Property("StatusCode").EqualTo(StatusCode.NotFound), () => client.Check(HealthCheckRequest.CreateBuilder().SetHost("").SetService("nonexistent.service").Build()));
+            Assert.Throws(Is.TypeOf(typeof(RpcException)).And.Property("Status").Property("StatusCode").EqualTo(StatusCode.NotFound), () => client.Check(new HealthCheckRequest{ Host = "", Service = "nonexistent.service" }));
         }
 
         // TODO(jtattermusch): add test with timeout once timeouts are supported
diff --git a/src/csharp/Grpc.HealthCheck.Tests/HealthServiceImplTest.cs b/src/csharp/Grpc.HealthCheck.Tests/HealthServiceImplTest.cs
index c4caa3b..8de8645 100644
--- a/src/csharp/Grpc.HealthCheck.Tests/HealthServiceImplTest.cs
+++ b/src/csharp/Grpc.HealthCheck.Tests/HealthServiceImplTest.cs
@@ -101,7 +101,7 @@
 
         private static HealthCheckResponse.Types.ServingStatus GetStatusHelper(HealthServiceImpl impl, string host, string service)
         {
-            return impl.Check(HealthCheckRequest.CreateBuilder().SetHost(host).SetService(service).Build(), null).Result.Status;
+            return impl.Check(new HealthCheckRequest{ Host = host, Service = service}, null).Result.Status;
         }
     }
 }
diff --git a/src/csharp/Grpc.HealthCheck.Tests/packages.config b/src/csharp/Grpc.HealthCheck.Tests/packages.config
index 050c4ea..40ffb85 100644
--- a/src/csharp/Grpc.HealthCheck.Tests/packages.config
+++ b/src/csharp/Grpc.HealthCheck.Tests/packages.config
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
 <packages>
-  <package id="Google.ProtocolBuffers" version="2.4.1.555" targetFramework="net45" />
+  <package id="Google.Protobuf" version="3.0.0-alpha4" targetFramework="net45" />
   <package id="NUnit" version="2.6.4" targetFramework="net45" />
 </packages>
\ No newline at end of file
diff --git a/src/csharp/Grpc.HealthCheck/Grpc.HealthCheck.csproj b/src/csharp/Grpc.HealthCheck/Grpc.HealthCheck.csproj
index 0b7a7b9..8fce5d3 100644
--- a/src/csharp/Grpc.HealthCheck/Grpc.HealthCheck.csproj
+++ b/src/csharp/Grpc.HealthCheck/Grpc.HealthCheck.csproj
@@ -38,11 +38,9 @@
     <AssemblyOriginatorKeyFile>C:\keys\Grpc.snk</AssemblyOriginatorKeyFile>
   </PropertyGroup>
   <ItemGroup>
-    <Reference Include="Google.ProtocolBuffers">
-      <HintPath>..\packages\Google.ProtocolBuffers.2.4.1.555\lib\net40\Google.ProtocolBuffers.dll</HintPath>
-    </Reference>
-    <Reference Include="Google.ProtocolBuffers.Serialization">
-      <HintPath>..\packages\Google.ProtocolBuffers.2.4.1.555\lib\net40\Google.ProtocolBuffers.Serialization.dll</HintPath>
+    <Reference Include="Google.Protobuf, Version=3.0.0.0, Culture=neutral, PublicKeyToken=a7d26565bac4d604, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\packages\Google.Protobuf.3.0.0-alpha4\lib\portable-net45+netcore45+wpa81+wp8\Google.Protobuf.dll</HintPath>
     </Reference>
     <Reference Include="System" />
     <Reference Include="System.Core" />
diff --git a/src/csharp/Grpc.HealthCheck/Grpc.HealthCheck.nuspec b/src/csharp/Grpc.HealthCheck/Grpc.HealthCheck.nuspec
index acdfba4..6638628 100644
--- a/src/csharp/Grpc.HealthCheck/Grpc.HealthCheck.nuspec
+++ b/src/csharp/Grpc.HealthCheck/Grpc.HealthCheck.nuspec
@@ -14,7 +14,7 @@
     <copyright>Copyright 2015, Google Inc.</copyright>
     <tags>gRPC health check</tags>
 	<dependencies>
-	  <dependency id="Google.ProtocolBuffers" version="2.4.1.555" />
+	  <dependency id="Google.Protobuf" version="$ProtobufVersion$" />
 	  <dependency id="Grpc.Core" version="$version$" />
 	  <dependency id="Ix-Async" version="1.2.3" />
     </dependencies>
diff --git a/src/csharp/Grpc.HealthCheck/Health.cs b/src/csharp/Grpc.HealthCheck/Health.cs
index 361382d..570e274 100644
--- a/src/csharp/Grpc.HealthCheck/Health.cs
+++ b/src/csharp/Grpc.HealthCheck/Health.cs
@@ -3,9 +3,9 @@
 #pragma warning disable 1591, 0612, 3021
 #region Designer generated code
 
-using pb = global::Google.ProtocolBuffers;
-using pbc = global::Google.ProtocolBuffers.Collections;
-using pbd = global::Google.ProtocolBuffers.Descriptors;
+using pb = global::Google.Protobuf;
+using pbc = global::Google.Protobuf.Collections;
+using pbr = global::Google.Protobuf.Reflection;
 using scg = global::System.Collections.Generic;
 namespace Grpc.Health.V1Alpha {
 
@@ -14,21 +14,11 @@
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
     public static partial class Health {
 
-      #region Extension registration
-      public static void RegisterAllExtensions(pb::ExtensionRegistry registry) {
-      }
-      #endregion
-      #region Static variables
-      internal static pbd::MessageDescriptor internal__static_grpc_health_v1alpha_HealthCheckRequest__Descriptor;
-      internal static pb::FieldAccess.FieldAccessorTable<global::Grpc.Health.V1Alpha.HealthCheckRequest, global::Grpc.Health.V1Alpha.HealthCheckRequest.Builder> internal__static_grpc_health_v1alpha_HealthCheckRequest__FieldAccessorTable;
-      internal static pbd::MessageDescriptor internal__static_grpc_health_v1alpha_HealthCheckResponse__Descriptor;
-      internal static pb::FieldAccess.FieldAccessorTable<global::Grpc.Health.V1Alpha.HealthCheckResponse, global::Grpc.Health.V1Alpha.HealthCheckResponse.Builder> internal__static_grpc_health_v1alpha_HealthCheckResponse__FieldAccessorTable;
-      #endregion
       #region Descriptor
-      public static pbd::FileDescriptor Descriptor {
+      public static pbr::FileDescriptor Descriptor {
         get { return descriptor; }
       }
-      private static pbd::FileDescriptor descriptor;
+      private static pbr::FileDescriptor descriptor;
 
       static Health() {
         byte[] descriptorData = global::System.Convert.FromBase64String(
@@ -41,24 +31,13 @@
               "EAESDwoLTk9UX1NFUlZJTkcQAjJkCgZIZWFsdGgSWgoFQ2hlY2sSJy5ncnBj", 
               "LmhlYWx0aC52MWFscGhhLkhlYWx0aENoZWNrUmVxdWVzdBooLmdycGMuaGVh", 
               "bHRoLnYxYWxwaGEuSGVhbHRoQ2hlY2tSZXNwb25zZUIWqgITR3JwYy5IZWFs", 
-            "dGguVjFBbHBoYQ=="));
-        pbd::FileDescriptor.InternalDescriptorAssigner assigner = delegate(pbd::FileDescriptor root) {
-          descriptor = root;
-          internal__static_grpc_health_v1alpha_HealthCheckRequest__Descriptor = Descriptor.MessageTypes[0];
-          internal__static_grpc_health_v1alpha_HealthCheckRequest__FieldAccessorTable = 
-              new pb::FieldAccess.FieldAccessorTable<global::Grpc.Health.V1Alpha.HealthCheckRequest, global::Grpc.Health.V1Alpha.HealthCheckRequest.Builder>(internal__static_grpc_health_v1alpha_HealthCheckRequest__Descriptor,
-                  new string[] { "Host", "Service", });
-          internal__static_grpc_health_v1alpha_HealthCheckResponse__Descriptor = Descriptor.MessageTypes[1];
-          internal__static_grpc_health_v1alpha_HealthCheckResponse__FieldAccessorTable = 
-              new pb::FieldAccess.FieldAccessorTable<global::Grpc.Health.V1Alpha.HealthCheckResponse, global::Grpc.Health.V1Alpha.HealthCheckResponse.Builder>(internal__static_grpc_health_v1alpha_HealthCheckResponse__Descriptor,
-                  new string[] { "Status", });
-          pb::ExtensionRegistry registry = pb::ExtensionRegistry.CreateInstance();
-          RegisterAllExtensions(registry);
-          return registry;
-        };
-        pbd::FileDescriptor.InternalBuildGeneratedFileFrom(descriptorData,
-            new pbd::FileDescriptor[] {
-            }, assigner);
+              "dGguVjFBbHBoYWIGcHJvdG8z"));
+        descriptor = pbr::FileDescriptor.InternalBuildGeneratedFileFrom(descriptorData,
+            new pbr::FileDescriptor[] { },
+            new pbr::GeneratedCodeInfo(null, new pbr::GeneratedCodeInfo[] {
+              new pbr::GeneratedCodeInfo(typeof(global::Grpc.Health.V1Alpha.HealthCheckRequest), new[]{ "Host", "Service" }, null, null, null),
+              new pbr::GeneratedCodeInfo(typeof(global::Grpc.Health.V1Alpha.HealthCheckResponse), new[]{ "Status" }, null, new[]{ typeof(global::Grpc.Health.V1Alpha.HealthCheckResponse.Types.ServingStatus) }, null)
+            }));
       }
       #endregion
 
@@ -66,349 +45,231 @@
   }
   #region Messages
   [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
-  public sealed partial class HealthCheckRequest : pb::GeneratedMessage<HealthCheckRequest, HealthCheckRequest.Builder> {
-    private HealthCheckRequest() { }
-    private static readonly HealthCheckRequest defaultInstance = new HealthCheckRequest().MakeReadOnly();
-    private static readonly string[] _healthCheckRequestFieldNames = new string[] { "host", "service" };
-    private static readonly uint[] _healthCheckRequestFieldTags = new uint[] { 10, 18 };
-    public static HealthCheckRequest DefaultInstance {
-      get { return defaultInstance; }
+  public sealed partial class HealthCheckRequest : pb::IMessage<HealthCheckRequest> {
+    private static readonly pb::MessageParser<HealthCheckRequest> _parser = new pb::MessageParser<HealthCheckRequest>(() => new HealthCheckRequest());
+    public static pb::MessageParser<HealthCheckRequest> Parser { get { return _parser; } }
+
+    public static pbr::MessageDescriptor Descriptor {
+      get { return global::Grpc.Health.V1Alpha.Proto.Health.Descriptor.MessageTypes[0]; }
     }
 
-    public override HealthCheckRequest DefaultInstanceForType {
-      get { return DefaultInstance; }
+    pbr::MessageDescriptor pb::IMessage.Descriptor {
+      get { return Descriptor; }
     }
 
-    protected override HealthCheckRequest ThisMessage {
-      get { return this; }
+    public HealthCheckRequest() {
+      OnConstruction();
     }
 
-    public static pbd::MessageDescriptor Descriptor {
-      get { return global::Grpc.Health.V1Alpha.Proto.Health.internal__static_grpc_health_v1alpha_HealthCheckRequest__Descriptor; }
+    partial void OnConstruction();
+
+    public HealthCheckRequest(HealthCheckRequest other) : this() {
+      host_ = other.host_;
+      service_ = other.service_;
     }
 
-    protected override pb::FieldAccess.FieldAccessorTable<HealthCheckRequest, HealthCheckRequest.Builder> InternalFieldAccessors {
-      get { return global::Grpc.Health.V1Alpha.Proto.Health.internal__static_grpc_health_v1alpha_HealthCheckRequest__FieldAccessorTable; }
+    public HealthCheckRequest Clone() {
+      return new HealthCheckRequest(this);
     }
 
     public const int HostFieldNumber = 1;
-    private bool hasHost;
     private string host_ = "";
-    public bool HasHost {
-      get { return hasHost; }
-    }
     public string Host {
       get { return host_; }
+      set {
+        host_ = pb::Preconditions.CheckNotNull(value, "value");
+      }
     }
 
     public const int ServiceFieldNumber = 2;
-    private bool hasService;
     private string service_ = "";
-    public bool HasService {
-      get { return hasService; }
-    }
     public string Service {
       get { return service_; }
+      set {
+        service_ = pb::Preconditions.CheckNotNull(value, "value");
+      }
     }
 
-    public override bool IsInitialized {
-      get {
+    public override bool Equals(object other) {
+      return Equals(other as HealthCheckRequest);
+    }
+
+    public bool Equals(HealthCheckRequest other) {
+      if (ReferenceEquals(other, null)) {
+        return false;
+      }
+      if (ReferenceEquals(other, this)) {
         return true;
       }
+      if (Host != other.Host) return false;
+      if (Service != other.Service) return false;
+      return true;
     }
 
-    public override void WriteTo(pb::ICodedOutputStream output) {
-      CalcSerializedSize();
-      string[] field_names = _healthCheckRequestFieldNames;
-      if (hasHost) {
-        output.WriteString(1, field_names[0], Host);
-      }
-      if (hasService) {
-        output.WriteString(2, field_names[1], Service);
-      }
-      UnknownFields.WriteTo(output);
+    public override int GetHashCode() {
+      int hash = 1;
+      if (Host.Length != 0) hash ^= Host.GetHashCode();
+      if (Service.Length != 0) hash ^= Service.GetHashCode();
+      return hash;
     }
 
-    private int memoizedSerializedSize = -1;
-    public override int SerializedSize {
-      get {
-        int size = memoizedSerializedSize;
-        if (size != -1) return size;
-        return CalcSerializedSize();
+    public override string ToString() {
+      return pb::JsonFormatter.Default.Format(this);
+    }
+
+    public void WriteTo(pb::CodedOutputStream output) {
+      if (Host.Length != 0) {
+        output.WriteRawTag(10);
+        output.WriteString(Host);
+      }
+      if (Service.Length != 0) {
+        output.WriteRawTag(18);
+        output.WriteString(Service);
       }
     }
 
-    private int CalcSerializedSize() {
-      int size = memoizedSerializedSize;
-      if (size != -1) return size;
-
-      size = 0;
-      if (hasHost) {
-        size += pb::CodedOutputStream.ComputeStringSize(1, Host);
+    public int CalculateSize() {
+      int size = 0;
+      if (Host.Length != 0) {
+        size += 1 + pb::CodedOutputStream.ComputeStringSize(Host);
       }
-      if (hasService) {
-        size += pb::CodedOutputStream.ComputeStringSize(2, Service);
+      if (Service.Length != 0) {
+        size += 1 + pb::CodedOutputStream.ComputeStringSize(Service);
       }
-      size += UnknownFields.SerializedSize;
-      memoizedSerializedSize = size;
       return size;
     }
-    public static HealthCheckRequest ParseFrom(pb::ByteString data) {
-      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
-    }
-    public static HealthCheckRequest ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
-      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
-    }
-    public static HealthCheckRequest ParseFrom(byte[] data) {
-      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
-    }
-    public static HealthCheckRequest ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
-      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
-    }
-    public static HealthCheckRequest ParseFrom(global::System.IO.Stream input) {
-      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
-    }
-    public static HealthCheckRequest ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
-      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
-    }
-    public static HealthCheckRequest ParseDelimitedFrom(global::System.IO.Stream input) {
-      return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
-    }
-    public static HealthCheckRequest ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
-      return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
-    }
-    public static HealthCheckRequest ParseFrom(pb::ICodedInputStream input) {
-      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
-    }
-    public static HealthCheckRequest ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
-      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
-    }
-    private HealthCheckRequest MakeReadOnly() {
-      return this;
+
+    public void MergeFrom(HealthCheckRequest other) {
+      if (other == null) {
+        return;
+      }
+      if (other.Host.Length != 0) {
+        Host = other.Host;
+      }
+      if (other.Service.Length != 0) {
+        Service = other.Service;
+      }
     }
 
-    public static Builder CreateBuilder() { return new Builder(); }
-    public override Builder ToBuilder() { return CreateBuilder(this); }
-    public override Builder CreateBuilderForType() { return new Builder(); }
-    public static Builder CreateBuilder(HealthCheckRequest prototype) {
-      return new Builder(prototype);
-    }
-
-    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
-    public sealed partial class Builder : pb::GeneratedBuilder<HealthCheckRequest, Builder> {
-      protected override Builder ThisBuilder {
-        get { return this; }
-      }
-      public Builder() {
-        result = DefaultInstance;
-        resultIsReadOnly = true;
-      }
-      internal Builder(HealthCheckRequest cloneFrom) {
-        result = cloneFrom;
-        resultIsReadOnly = true;
-      }
-
-      private bool resultIsReadOnly;
-      private HealthCheckRequest result;
-
-      private HealthCheckRequest PrepareBuilder() {
-        if (resultIsReadOnly) {
-          HealthCheckRequest original = result;
-          result = new HealthCheckRequest();
-          resultIsReadOnly = false;
-          MergeFrom(original);
-        }
-        return result;
-      }
-
-      public override bool IsInitialized {
-        get { return result.IsInitialized; }
-      }
-
-      protected override HealthCheckRequest MessageBeingBuilt {
-        get { return PrepareBuilder(); }
-      }
-
-      public override Builder Clear() {
-        result = DefaultInstance;
-        resultIsReadOnly = true;
-        return this;
-      }
-
-      public override Builder Clone() {
-        if (resultIsReadOnly) {
-          return new Builder(result);
-        } else {
-          return new Builder().MergeFrom(result);
-        }
-      }
-
-      public override pbd::MessageDescriptor DescriptorForType {
-        get { return global::Grpc.Health.V1Alpha.HealthCheckRequest.Descriptor; }
-      }
-
-      public override HealthCheckRequest DefaultInstanceForType {
-        get { return global::Grpc.Health.V1Alpha.HealthCheckRequest.DefaultInstance; }
-      }
-
-      public override HealthCheckRequest BuildPartial() {
-        if (resultIsReadOnly) {
-          return result;
-        }
-        resultIsReadOnly = true;
-        return result.MakeReadOnly();
-      }
-
-      public override Builder MergeFrom(pb::IMessage other) {
-        if (other is HealthCheckRequest) {
-          return MergeFrom((HealthCheckRequest) other);
-        } else {
-          base.MergeFrom(other);
-          return this;
-        }
-      }
-
-      public override Builder MergeFrom(HealthCheckRequest other) {
-        if (other == global::Grpc.Health.V1Alpha.HealthCheckRequest.DefaultInstance) return this;
-        PrepareBuilder();
-        if (other.HasHost) {
-          Host = other.Host;
-        }
-        if (other.HasService) {
-          Service = other.Service;
-        }
-        this.MergeUnknownFields(other.UnknownFields);
-        return this;
-      }
-
-      public override Builder MergeFrom(pb::ICodedInputStream input) {
-        return MergeFrom(input, pb::ExtensionRegistry.Empty);
-      }
-
-      public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
-        PrepareBuilder();
-        pb::UnknownFieldSet.Builder unknownFields = null;
-        uint tag;
-        string field_name;
-        while (input.ReadTag(out tag, out field_name)) {
-          if(tag == 0 && field_name != null) {
-            int field_ordinal = global::System.Array.BinarySearch(_healthCheckRequestFieldNames, field_name, global::System.StringComparer.Ordinal);
-            if(field_ordinal >= 0)
-              tag = _healthCheckRequestFieldTags[field_ordinal];
-            else {
-              if (unknownFields == null) {
-                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
-              }
-              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);
-              continue;
-            }
+    public void MergeFrom(pb::CodedInputStream input) {
+      uint tag;
+      while ((tag = input.ReadTag()) != 0) {
+        switch(tag) {
+          default:
+            input.SkipLastField();
+            break;
+          case 10: {
+            Host = input.ReadString();
+            break;
           }
-          switch (tag) {
-            case 0: {
-              throw pb::InvalidProtocolBufferException.InvalidTag();
-            }
-            default: {
-              if (pb::WireFormat.IsEndGroupTag(tag)) {
-                if (unknownFields != null) {
-                  this.UnknownFields = unknownFields.Build();
-                }
-                return this;
-              }
-              if (unknownFields == null) {
-                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
-              }
-              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);
-              break;
-            }
-            case 10: {
-              result.hasHost = input.ReadString(ref result.host_);
-              break;
-            }
-            case 18: {
-              result.hasService = input.ReadString(ref result.service_);
-              break;
-            }
+          case 18: {
+            Service = input.ReadString();
+            break;
           }
         }
-
-        if (unknownFields != null) {
-          this.UnknownFields = unknownFields.Build();
-        }
-        return this;
-      }
-
-
-      public bool HasHost {
-        get { return result.hasHost; }
-      }
-      public string Host {
-        get { return result.Host; }
-        set { SetHost(value); }
-      }
-      public Builder SetHost(string value) {
-        pb::ThrowHelper.ThrowIfNull(value, "value");
-        PrepareBuilder();
-        result.hasHost = true;
-        result.host_ = value;
-        return this;
-      }
-      public Builder ClearHost() {
-        PrepareBuilder();
-        result.hasHost = false;
-        result.host_ = "";
-        return this;
-      }
-
-      public bool HasService {
-        get { return result.hasService; }
-      }
-      public string Service {
-        get { return result.Service; }
-        set { SetService(value); }
-      }
-      public Builder SetService(string value) {
-        pb::ThrowHelper.ThrowIfNull(value, "value");
-        PrepareBuilder();
-        result.hasService = true;
-        result.service_ = value;
-        return this;
-      }
-      public Builder ClearService() {
-        PrepareBuilder();
-        result.hasService = false;
-        result.service_ = "";
-        return this;
       }
     }
-    static HealthCheckRequest() {
-      object.ReferenceEquals(global::Grpc.Health.V1Alpha.Proto.Health.Descriptor, null);
-    }
+
   }
 
   [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
-  public sealed partial class HealthCheckResponse : pb::GeneratedMessage<HealthCheckResponse, HealthCheckResponse.Builder> {
-    private HealthCheckResponse() { }
-    private static readonly HealthCheckResponse defaultInstance = new HealthCheckResponse().MakeReadOnly();
-    private static readonly string[] _healthCheckResponseFieldNames = new string[] { "status" };
-    private static readonly uint[] _healthCheckResponseFieldTags = new uint[] { 8 };
-    public static HealthCheckResponse DefaultInstance {
-      get { return defaultInstance; }
+  public sealed partial class HealthCheckResponse : pb::IMessage<HealthCheckResponse> {
+    private static readonly pb::MessageParser<HealthCheckResponse> _parser = new pb::MessageParser<HealthCheckResponse>(() => new HealthCheckResponse());
+    public static pb::MessageParser<HealthCheckResponse> Parser { get { return _parser; } }
+
+    public static pbr::MessageDescriptor Descriptor {
+      get { return global::Grpc.Health.V1Alpha.Proto.Health.Descriptor.MessageTypes[1]; }
     }
 
-    public override HealthCheckResponse DefaultInstanceForType {
-      get { return DefaultInstance; }
+    pbr::MessageDescriptor pb::IMessage.Descriptor {
+      get { return Descriptor; }
     }
 
-    protected override HealthCheckResponse ThisMessage {
-      get { return this; }
+    public HealthCheckResponse() {
+      OnConstruction();
     }
 
-    public static pbd::MessageDescriptor Descriptor {
-      get { return global::Grpc.Health.V1Alpha.Proto.Health.internal__static_grpc_health_v1alpha_HealthCheckResponse__Descriptor; }
+    partial void OnConstruction();
+
+    public HealthCheckResponse(HealthCheckResponse other) : this() {
+      status_ = other.status_;
     }
 
-    protected override pb::FieldAccess.FieldAccessorTable<HealthCheckResponse, HealthCheckResponse.Builder> InternalFieldAccessors {
-      get { return global::Grpc.Health.V1Alpha.Proto.Health.internal__static_grpc_health_v1alpha_HealthCheckResponse__FieldAccessorTable; }
+    public HealthCheckResponse Clone() {
+      return new HealthCheckResponse(this);
+    }
+
+    public const int StatusFieldNumber = 1;
+    private global::Grpc.Health.V1Alpha.HealthCheckResponse.Types.ServingStatus status_ = global::Grpc.Health.V1Alpha.HealthCheckResponse.Types.ServingStatus.UNKNOWN;
+    public global::Grpc.Health.V1Alpha.HealthCheckResponse.Types.ServingStatus Status {
+      get { return status_; }
+      set {
+        status_ = value;
+      }
+    }
+
+    public override bool Equals(object other) {
+      return Equals(other as HealthCheckResponse);
+    }
+
+    public bool Equals(HealthCheckResponse other) {
+      if (ReferenceEquals(other, null)) {
+        return false;
+      }
+      if (ReferenceEquals(other, this)) {
+        return true;
+      }
+      if (Status != other.Status) return false;
+      return true;
+    }
+
+    public override int GetHashCode() {
+      int hash = 1;
+      if (Status != global::Grpc.Health.V1Alpha.HealthCheckResponse.Types.ServingStatus.UNKNOWN) hash ^= Status.GetHashCode();
+      return hash;
+    }
+
+    public override string ToString() {
+      return pb::JsonFormatter.Default.Format(this);
+    }
+
+    public void WriteTo(pb::CodedOutputStream output) {
+      if (Status != global::Grpc.Health.V1Alpha.HealthCheckResponse.Types.ServingStatus.UNKNOWN) {
+        output.WriteRawTag(8);
+        output.WriteEnum((int) Status);
+      }
+    }
+
+    public int CalculateSize() {
+      int size = 0;
+      if (Status != global::Grpc.Health.V1Alpha.HealthCheckResponse.Types.ServingStatus.UNKNOWN) {
+        size += 1 + pb::CodedOutputStream.ComputeEnumSize((int) Status);
+      }
+      return size;
+    }
+
+    public void MergeFrom(HealthCheckResponse other) {
+      if (other == null) {
+        return;
+      }
+      if (other.Status != global::Grpc.Health.V1Alpha.HealthCheckResponse.Types.ServingStatus.UNKNOWN) {
+        Status = other.Status;
+      }
+    }
+
+    public void MergeFrom(pb::CodedInputStream input) {
+      uint tag;
+      while ((tag = input.ReadTag()) != 0) {
+        switch(tag) {
+          default:
+            input.SkipLastField();
+            break;
+          case 8: {
+            status_ = (global::Grpc.Health.V1Alpha.HealthCheckResponse.Types.ServingStatus) input.ReadEnum();
+            break;
+          }
+        }
+      }
     }
 
     #region Nested types
@@ -423,261 +284,6 @@
     }
     #endregion
 
-    public const int StatusFieldNumber = 1;
-    private bool hasStatus;
-    private global::Grpc.Health.V1Alpha.HealthCheckResponse.Types.ServingStatus status_ = global::Grpc.Health.V1Alpha.HealthCheckResponse.Types.ServingStatus.UNKNOWN;
-    public bool HasStatus {
-      get { return hasStatus; }
-    }
-    public global::Grpc.Health.V1Alpha.HealthCheckResponse.Types.ServingStatus Status {
-      get { return status_; }
-    }
-
-    public override bool IsInitialized {
-      get {
-        return true;
-      }
-    }
-
-    public override void WriteTo(pb::ICodedOutputStream output) {
-      CalcSerializedSize();
-      string[] field_names = _healthCheckResponseFieldNames;
-      if (hasStatus) {
-        output.WriteEnum(1, field_names[0], (int) Status, Status);
-      }
-      UnknownFields.WriteTo(output);
-    }
-
-    private int memoizedSerializedSize = -1;
-    public override int SerializedSize {
-      get {
-        int size = memoizedSerializedSize;
-        if (size != -1) return size;
-        return CalcSerializedSize();
-      }
-    }
-
-    private int CalcSerializedSize() {
-      int size = memoizedSerializedSize;
-      if (size != -1) return size;
-
-      size = 0;
-      if (hasStatus) {
-        size += pb::CodedOutputStream.ComputeEnumSize(1, (int) Status);
-      }
-      size += UnknownFields.SerializedSize;
-      memoizedSerializedSize = size;
-      return size;
-    }
-    public static HealthCheckResponse ParseFrom(pb::ByteString data) {
-      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
-    }
-    public static HealthCheckResponse ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
-      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
-    }
-    public static HealthCheckResponse ParseFrom(byte[] data) {
-      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
-    }
-    public static HealthCheckResponse ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
-      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
-    }
-    public static HealthCheckResponse ParseFrom(global::System.IO.Stream input) {
-      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
-    }
-    public static HealthCheckResponse ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
-      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
-    }
-    public static HealthCheckResponse ParseDelimitedFrom(global::System.IO.Stream input) {
-      return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
-    }
-    public static HealthCheckResponse ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
-      return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
-    }
-    public static HealthCheckResponse ParseFrom(pb::ICodedInputStream input) {
-      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
-    }
-    public static HealthCheckResponse ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
-      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
-    }
-    private HealthCheckResponse MakeReadOnly() {
-      return this;
-    }
-
-    public static Builder CreateBuilder() { return new Builder(); }
-    public override Builder ToBuilder() { return CreateBuilder(this); }
-    public override Builder CreateBuilderForType() { return new Builder(); }
-    public static Builder CreateBuilder(HealthCheckResponse prototype) {
-      return new Builder(prototype);
-    }
-
-    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
-    public sealed partial class Builder : pb::GeneratedBuilder<HealthCheckResponse, Builder> {
-      protected override Builder ThisBuilder {
-        get { return this; }
-      }
-      public Builder() {
-        result = DefaultInstance;
-        resultIsReadOnly = true;
-      }
-      internal Builder(HealthCheckResponse cloneFrom) {
-        result = cloneFrom;
-        resultIsReadOnly = true;
-      }
-
-      private bool resultIsReadOnly;
-      private HealthCheckResponse result;
-
-      private HealthCheckResponse PrepareBuilder() {
-        if (resultIsReadOnly) {
-          HealthCheckResponse original = result;
-          result = new HealthCheckResponse();
-          resultIsReadOnly = false;
-          MergeFrom(original);
-        }
-        return result;
-      }
-
-      public override bool IsInitialized {
-        get { return result.IsInitialized; }
-      }
-
-      protected override HealthCheckResponse MessageBeingBuilt {
-        get { return PrepareBuilder(); }
-      }
-
-      public override Builder Clear() {
-        result = DefaultInstance;
-        resultIsReadOnly = true;
-        return this;
-      }
-
-      public override Builder Clone() {
-        if (resultIsReadOnly) {
-          return new Builder(result);
-        } else {
-          return new Builder().MergeFrom(result);
-        }
-      }
-
-      public override pbd::MessageDescriptor DescriptorForType {
-        get { return global::Grpc.Health.V1Alpha.HealthCheckResponse.Descriptor; }
-      }
-
-      public override HealthCheckResponse DefaultInstanceForType {
-        get { return global::Grpc.Health.V1Alpha.HealthCheckResponse.DefaultInstance; }
-      }
-
-      public override HealthCheckResponse BuildPartial() {
-        if (resultIsReadOnly) {
-          return result;
-        }
-        resultIsReadOnly = true;
-        return result.MakeReadOnly();
-      }
-
-      public override Builder MergeFrom(pb::IMessage other) {
-        if (other is HealthCheckResponse) {
-          return MergeFrom((HealthCheckResponse) other);
-        } else {
-          base.MergeFrom(other);
-          return this;
-        }
-      }
-
-      public override Builder MergeFrom(HealthCheckResponse other) {
-        if (other == global::Grpc.Health.V1Alpha.HealthCheckResponse.DefaultInstance) return this;
-        PrepareBuilder();
-        if (other.HasStatus) {
-          Status = other.Status;
-        }
-        this.MergeUnknownFields(other.UnknownFields);
-        return this;
-      }
-
-      public override Builder MergeFrom(pb::ICodedInputStream input) {
-        return MergeFrom(input, pb::ExtensionRegistry.Empty);
-      }
-
-      public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
-        PrepareBuilder();
-        pb::UnknownFieldSet.Builder unknownFields = null;
-        uint tag;
-        string field_name;
-        while (input.ReadTag(out tag, out field_name)) {
-          if(tag == 0 && field_name != null) {
-            int field_ordinal = global::System.Array.BinarySearch(_healthCheckResponseFieldNames, field_name, global::System.StringComparer.Ordinal);
-            if(field_ordinal >= 0)
-              tag = _healthCheckResponseFieldTags[field_ordinal];
-            else {
-              if (unknownFields == null) {
-                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
-              }
-              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);
-              continue;
-            }
-          }
-          switch (tag) {
-            case 0: {
-              throw pb::InvalidProtocolBufferException.InvalidTag();
-            }
-            default: {
-              if (pb::WireFormat.IsEndGroupTag(tag)) {
-                if (unknownFields != null) {
-                  this.UnknownFields = unknownFields.Build();
-                }
-                return this;
-              }
-              if (unknownFields == null) {
-                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
-              }
-              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);
-              break;
-            }
-            case 8: {
-              object unknown;
-              if(input.ReadEnum(ref result.status_, out unknown)) {
-                result.hasStatus = true;
-              } else if(unknown is int) {
-                if (unknownFields == null) {
-                  unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
-                }
-                unknownFields.MergeVarintField(1, (ulong)(int)unknown);
-              }
-              break;
-            }
-          }
-        }
-
-        if (unknownFields != null) {
-          this.UnknownFields = unknownFields.Build();
-        }
-        return this;
-      }
-
-
-      public bool HasStatus {
-       get { return result.hasStatus; }
-      }
-      public global::Grpc.Health.V1Alpha.HealthCheckResponse.Types.ServingStatus Status {
-        get { return result.Status; }
-        set { SetStatus(value); }
-      }
-      public Builder SetStatus(global::Grpc.Health.V1Alpha.HealthCheckResponse.Types.ServingStatus value) {
-        PrepareBuilder();
-        result.hasStatus = true;
-        result.status_ = value;
-        return this;
-      }
-      public Builder ClearStatus() {
-        PrepareBuilder();
-        result.hasStatus = false;
-        result.status_ = global::Grpc.Health.V1Alpha.HealthCheckResponse.Types.ServingStatus.UNKNOWN;
-        return this;
-      }
-    }
-    static HealthCheckResponse() {
-      object.ReferenceEquals(global::Grpc.Health.V1Alpha.Proto.Health.Descriptor, null);
-    }
   }
 
   #endregion
diff --git a/src/csharp/Grpc.HealthCheck/HealthGrpc.cs b/src/csharp/Grpc.HealthCheck/HealthGrpc.cs
index 0dabc91..da721ce 100644
--- a/src/csharp/Grpc.HealthCheck/HealthGrpc.cs
+++ b/src/csharp/Grpc.HealthCheck/HealthGrpc.cs
@@ -12,8 +12,8 @@
   {
     static readonly string __ServiceName = "grpc.health.v1alpha.Health";
 
-    static readonly Marshaller<global::Grpc.Health.V1Alpha.HealthCheckRequest> __Marshaller_HealthCheckRequest = Marshallers.Create((arg) => arg.ToByteArray(), global::Grpc.Health.V1Alpha.HealthCheckRequest.ParseFrom);
-    static readonly Marshaller<global::Grpc.Health.V1Alpha.HealthCheckResponse> __Marshaller_HealthCheckResponse = Marshallers.Create((arg) => arg.ToByteArray(), global::Grpc.Health.V1Alpha.HealthCheckResponse.ParseFrom);
+    static readonly Marshaller<global::Grpc.Health.V1Alpha.HealthCheckRequest> __Marshaller_HealthCheckRequest = Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Health.V1Alpha.HealthCheckRequest.Parser.ParseFrom);
+    static readonly Marshaller<global::Grpc.Health.V1Alpha.HealthCheckResponse> __Marshaller_HealthCheckResponse = Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Health.V1Alpha.HealthCheckResponse.Parser.ParseFrom);
 
     static readonly Method<global::Grpc.Health.V1Alpha.HealthCheckRequest, global::Grpc.Health.V1Alpha.HealthCheckResponse> __Method_Check = new Method<global::Grpc.Health.V1Alpha.HealthCheckRequest, global::Grpc.Health.V1Alpha.HealthCheckResponse>(
         MethodType.Unary,
@@ -22,6 +22,12 @@
         __Marshaller_HealthCheckRequest,
         __Marshaller_HealthCheckResponse);
 
+    // service descriptor
+    public static global::Google.Protobuf.Reflection.ServiceDescriptor Descriptor
+    {
+      get { return global::Grpc.Health.V1Alpha.Proto.Health.Descriptor.Services[0]; }
+    }
+
     // client interface
     public interface IHealthClient
     {
diff --git a/src/csharp/Grpc.HealthCheck/HealthServiceImpl.cs b/src/csharp/Grpc.HealthCheck/HealthServiceImpl.cs
index 8c04b43..26c6445 100644
--- a/src/csharp/Grpc.HealthCheck/HealthServiceImpl.cs
+++ b/src/csharp/Grpc.HealthCheck/HealthServiceImpl.cs
@@ -105,8 +105,8 @@
         {
             lock (myLock)
             {
-                var host = request.HasHost ? request.Host : "";
-                var service = request.HasService ? request.Service : "";
+                var host = request.Host;
+                var service = request.Service;
 
                 HealthCheckResponse.Types.ServingStatus status;
                 if (!statusMap.TryGetValue(CreateKey(host, service), out status))
@@ -114,7 +114,7 @@
                     // TODO(jtattermusch): returning specific status from server handler is not supported yet.
                     throw new RpcException(new Status(StatusCode.NotFound, ""));
                 }
-                return Task.FromResult(HealthCheckResponse.CreateBuilder().SetStatus(status).Build());
+                return Task.FromResult(new HealthCheckResponse { Status = status });
             }
         }
 
diff --git a/src/csharp/Grpc.HealthCheck/packages.config b/src/csharp/Grpc.HealthCheck/packages.config
index 094a309..cafff61 100644
--- a/src/csharp/Grpc.HealthCheck/packages.config
+++ b/src/csharp/Grpc.HealthCheck/packages.config
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
 <packages>
-  <package id="Google.ProtocolBuffers" version="2.4.1.555" targetFramework="net45" />
+  <package id="Google.Protobuf" version="3.0.0-alpha4" targetFramework="net45" />
   <package id="Ix-Async" version="1.2.3" targetFramework="net45" />
 </packages>
\ No newline at end of file
diff --git a/src/csharp/Grpc.HealthCheck/proto/health.proto b/src/csharp/Grpc.HealthCheck/proto/health.proto
index 08df7e1..01aa3fc 100644
--- a/src/csharp/Grpc.HealthCheck/proto/health.proto
+++ b/src/csharp/Grpc.HealthCheck/proto/health.proto
@@ -28,14 +28,14 @@
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 // TODO(jtattermusch): switch to proto3 once C# supports that.
-syntax = "proto2";
+syntax = "proto3";
 
 package grpc.health.v1alpha;
 option csharp_namespace = "Grpc.Health.V1Alpha";
 
 message HealthCheckRequest {
-  optional string host = 1;
-  optional string service = 2;
+  string host = 1;
+  string service = 2;
 }
 
 message HealthCheckResponse {
@@ -44,7 +44,7 @@
     SERVING = 1;
     NOT_SERVING = 2;
   }
-  optional ServingStatus status = 1;
+  ServingStatus status = 1;
 }
 
 service Health {
diff --git a/src/csharp/Grpc.IntegrationTesting/Empty.cs b/src/csharp/Grpc.IntegrationTesting/Empty.cs
index 7169ee2..28c28c9 100644
--- a/src/csharp/Grpc.IntegrationTesting/Empty.cs
+++ b/src/csharp/Grpc.IntegrationTesting/Empty.cs
@@ -1,47 +1,34 @@
-// Generated by ProtoGen, Version=2.4.1.521, Culture=neutral, PublicKeyToken=17b3b1f090c3ea48.  DO NOT EDIT!
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: empty.proto
 #pragma warning disable 1591, 0612, 3021
 #region Designer generated code
 
-using pb = global::Google.ProtocolBuffers;
-using pbc = global::Google.ProtocolBuffers.Collections;
-using pbd = global::Google.ProtocolBuffers.Descriptors;
+using pb = global::Google.Protobuf;
+using pbc = global::Google.Protobuf.Collections;
+using pbr = global::Google.Protobuf.Reflection;
 using scg = global::System.Collections.Generic;
-namespace grpc.testing {
+namespace Grpc.Testing {
 
   namespace Proto {
 
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
     public static partial class Empty {
 
-      #region Extension registration
-      public static void RegisterAllExtensions(pb::ExtensionRegistry registry) {
-      }
-      #endregion
-      #region Static variables
-      internal static pbd::MessageDescriptor internal__static_grpc_testing_Empty__Descriptor;
-      internal static pb::FieldAccess.FieldAccessorTable<global::grpc.testing.Empty, global::grpc.testing.Empty.Builder> internal__static_grpc_testing_Empty__FieldAccessorTable;
-      #endregion
       #region Descriptor
-      public static pbd::FileDescriptor Descriptor {
+      public static pbr::FileDescriptor Descriptor {
         get { return descriptor; }
       }
-      private static pbd::FileDescriptor descriptor;
+      private static pbr::FileDescriptor descriptor;
 
       static Empty() {
         byte[] descriptorData = global::System.Convert.FromBase64String(
             string.Concat(
-            "CgtlbXB0eS5wcm90bxIMZ3JwYy50ZXN0aW5nIgcKBUVtcHR5"));
-        pbd::FileDescriptor.InternalDescriptorAssigner assigner = delegate(pbd::FileDescriptor root) {
-          descriptor = root;
-          internal__static_grpc_testing_Empty__Descriptor = Descriptor.MessageTypes[0];
-          internal__static_grpc_testing_Empty__FieldAccessorTable =
-              new pb::FieldAccess.FieldAccessorTable<global::grpc.testing.Empty, global::grpc.testing.Empty.Builder>(internal__static_grpc_testing_Empty__Descriptor,
-                  new string[] { });
-          return null;
-        };
-        pbd::FileDescriptor.InternalBuildGeneratedFileFrom(descriptorData,
-            new pbd::FileDescriptor[] {
-            }, assigner);
+              "CgtlbXB0eS5wcm90bxIMZ3JwYy50ZXN0aW5nIgcKBUVtcHR5YgZwcm90bzM="));
+        descriptor = pbr::FileDescriptor.InternalBuildGeneratedFileFrom(descriptorData,
+            new pbr::FileDescriptor[] { },
+            new pbr::GeneratedCodeInfo(null, new pbr::GeneratedCodeInfo[] {
+              new pbr::GeneratedCodeInfo(typeof(global::Grpc.Testing.Empty), null, null, null, null)
+            }));
       }
       #endregion
 
@@ -49,230 +36,79 @@
   }
   #region Messages
   [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
-  public sealed partial class Empty : pb::GeneratedMessage<Empty, Empty.Builder> {
-    private Empty() { }
-    private static readonly Empty defaultInstance = new Empty().MakeReadOnly();
-    private static readonly string[] _emptyFieldNames = new string[] {  };
-    private static readonly uint[] _emptyFieldTags = new uint[] {  };
-    public static Empty DefaultInstance {
-      get { return defaultInstance; }
+  public sealed partial class Empty : pb::IMessage<Empty> {
+    private static readonly pb::MessageParser<Empty> _parser = new pb::MessageParser<Empty>(() => new Empty());
+    public static pb::MessageParser<Empty> Parser { get { return _parser; } }
+
+    public static pbr::MessageDescriptor Descriptor {
+      get { return global::Grpc.Testing.Proto.Empty.Descriptor.MessageTypes[0]; }
     }
 
-    public override Empty DefaultInstanceForType {
-      get { return DefaultInstance; }
+    pbr::MessageDescriptor pb::IMessage.Descriptor {
+      get { return Descriptor; }
     }
 
-    protected override Empty ThisMessage {
-      get { return this; }
+    public Empty() {
+      OnConstruction();
     }
 
-    public static pbd::MessageDescriptor Descriptor {
-      get { return global::grpc.testing.Proto.Empty.internal__static_grpc_testing_Empty__Descriptor; }
+    partial void OnConstruction();
+
+    public Empty(Empty other) : this() {
     }
 
-    protected override pb::FieldAccess.FieldAccessorTable<Empty, Empty.Builder> InternalFieldAccessors {
-      get { return global::grpc.testing.Proto.Empty.internal__static_grpc_testing_Empty__FieldAccessorTable; }
+    public Empty Clone() {
+      return new Empty(this);
     }
 
-    public override bool IsInitialized {
-      get {
+    public override bool Equals(object other) {
+      return Equals(other as Empty);
+    }
+
+    public bool Equals(Empty other) {
+      if (ReferenceEquals(other, null)) {
+        return false;
+      }
+      if (ReferenceEquals(other, this)) {
         return true;
       }
+      return true;
     }
 
-    public override void WriteTo(pb::ICodedOutputStream output) {
-      int size = SerializedSize;
-      string[] field_names = _emptyFieldNames;
-      UnknownFields.WriteTo(output);
+    public override int GetHashCode() {
+      int hash = 1;
+      return hash;
     }
 
-    private int memoizedSerializedSize = -1;
-    public override int SerializedSize {
-      get {
-        int size = memoizedSerializedSize;
-        if (size != -1) return size;
+    public override string ToString() {
+      return pb::JsonFormatter.Default.Format(this);
+    }
 
-        size = 0;
-        size += UnknownFields.SerializedSize;
-        memoizedSerializedSize = size;
-        return size;
+    public void WriteTo(pb::CodedOutputStream output) {
+    }
+
+    public int CalculateSize() {
+      int size = 0;
+      return size;
+    }
+
+    public void MergeFrom(Empty other) {
+      if (other == null) {
+        return;
       }
     }
 
-    public static Empty ParseFrom(pb::ByteString data) {
-      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
-    }
-    public static Empty ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
-      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
-    }
-    public static Empty ParseFrom(byte[] data) {
-      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
-    }
-    public static Empty ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
-      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
-    }
-    public static Empty ParseFrom(global::System.IO.Stream input) {
-      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
-    }
-    public static Empty ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
-      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
-    }
-    public static Empty ParseDelimitedFrom(global::System.IO.Stream input) {
-      return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
-    }
-    public static Empty ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
-      return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
-    }
-    public static Empty ParseFrom(pb::ICodedInputStream input) {
-      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
-    }
-    public static Empty ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
-      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
-    }
-    private Empty MakeReadOnly() {
-      return this;
-    }
-
-    public static Builder CreateBuilder() { return new Builder(); }
-    public override Builder ToBuilder() { return CreateBuilder(this); }
-    public override Builder CreateBuilderForType() { return new Builder(); }
-    public static Builder CreateBuilder(Empty prototype) {
-      return new Builder(prototype);
-    }
-
-    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
-    public sealed partial class Builder : pb::GeneratedBuilder<Empty, Builder> {
-      protected override Builder ThisBuilder {
-        get { return this; }
-      }
-      public Builder() {
-        result = DefaultInstance;
-        resultIsReadOnly = true;
-      }
-      internal Builder(Empty cloneFrom) {
-        result = cloneFrom;
-        resultIsReadOnly = true;
-      }
-
-      private bool resultIsReadOnly;
-      private Empty result;
-
-      private Empty PrepareBuilder() {
-        if (resultIsReadOnly) {
-          Empty original = result;
-          result = new Empty();
-          resultIsReadOnly = false;
-          MergeFrom(original);
-        }
-        return result;
-      }
-
-      public override bool IsInitialized {
-        get { return result.IsInitialized; }
-      }
-
-      protected override Empty MessageBeingBuilt {
-        get { return PrepareBuilder(); }
-      }
-
-      public override Builder Clear() {
-        result = DefaultInstance;
-        resultIsReadOnly = true;
-        return this;
-      }
-
-      public override Builder Clone() {
-        if (resultIsReadOnly) {
-          return new Builder(result);
-        } else {
-          return new Builder().MergeFrom(result);
+    public void MergeFrom(pb::CodedInputStream input) {
+      uint tag;
+      while ((tag = input.ReadTag()) != 0) {
+        switch(tag) {
+          default:
+            input.SkipLastField();
+            break;
         }
       }
-
-      public override pbd::MessageDescriptor DescriptorForType {
-        get { return global::grpc.testing.Empty.Descriptor; }
-      }
-
-      public override Empty DefaultInstanceForType {
-        get { return global::grpc.testing.Empty.DefaultInstance; }
-      }
-
-      public override Empty BuildPartial() {
-        if (resultIsReadOnly) {
-          return result;
-        }
-        resultIsReadOnly = true;
-        return result.MakeReadOnly();
-      }
-
-      public override Builder MergeFrom(pb::IMessage other) {
-        if (other is Empty) {
-          return MergeFrom((Empty) other);
-        } else {
-          base.MergeFrom(other);
-          return this;
-        }
-      }
-
-      public override Builder MergeFrom(Empty other) {
-        if (other == global::grpc.testing.Empty.DefaultInstance) return this;
-        PrepareBuilder();
-        this.MergeUnknownFields(other.UnknownFields);
-        return this;
-      }
-
-      public override Builder MergeFrom(pb::ICodedInputStream input) {
-        return MergeFrom(input, pb::ExtensionRegistry.Empty);
-      }
-
-      public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
-        PrepareBuilder();
-        pb::UnknownFieldSet.Builder unknownFields = null;
-        uint tag;
-        string field_name;
-        while (input.ReadTag(out tag, out field_name)) {
-          if(tag == 0 && field_name != null) {
-            int field_ordinal = global::System.Array.BinarySearch(_emptyFieldNames, field_name, global::System.StringComparer.Ordinal);
-            if(field_ordinal >= 0)
-              tag = _emptyFieldTags[field_ordinal];
-            else {
-              if (unknownFields == null) {
-                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
-              }
-              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);
-              continue;
-            }
-          }
-          switch (tag) {
-            case 0: {
-              throw pb::InvalidProtocolBufferException.InvalidTag();
-            }
-            default: {
-              if (pb::WireFormat.IsEndGroupTag(tag)) {
-                if (unknownFields != null) {
-                  this.UnknownFields = unknownFields.Build();
-                }
-                return this;
-              }
-              if (unknownFields == null) {
-                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
-              }
-              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);
-              break;
-            }
-          }
-        }
-
-        if (unknownFields != null) {
-          this.UnknownFields = unknownFields.Build();
-        }
-        return this;
-      }
-
     }
-    static Empty() {
-      object.ReferenceEquals(global::grpc.testing.Proto.Empty.Descriptor, null);
-    }
+
   }
 
   #endregion
diff --git a/src/csharp/Grpc.IntegrationTesting/Grpc.IntegrationTesting.csproj b/src/csharp/Grpc.IntegrationTesting/Grpc.IntegrationTesting.csproj
index 2020a76..a5945be 100644
--- a/src/csharp/Grpc.IntegrationTesting/Grpc.IntegrationTesting.csproj
+++ b/src/csharp/Grpc.IntegrationTesting/Grpc.IntegrationTesting.csproj
@@ -54,6 +54,10 @@
       <SpecificVersion>False</SpecificVersion>
       <HintPath>..\packages\Google.Apis.Core.1.9.3\lib\portable-net40+sl50+win+wpa81+wp80\Google.Apis.Core.dll</HintPath>
     </Reference>
+    <Reference Include="Google.Protobuf, Version=3.0.0.0, Culture=neutral, PublicKeyToken=a7d26565bac4d604, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\packages\Google.Protobuf.3.0.0-alpha4\lib\portable-net45+netcore45+wpa81+wp8\Google.Protobuf.dll</HintPath>
+    </Reference>
     <Reference Include="Microsoft.Threading.Tasks, Version=1.0.12.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
       <SpecificVersion>False</SpecificVersion>
       <HintPath>..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.dll</HintPath>
@@ -74,22 +78,11 @@
       <HintPath>..\packages\NUnit.2.6.4\lib\nunit.framework.dll</HintPath>
     </Reference>
     <Reference Include="System" />
-    <Reference Include="Google.ProtocolBuffers">
-      <HintPath>..\packages\Google.ProtocolBuffers.2.4.1.521\lib\net40\Google.ProtocolBuffers.dll</HintPath>
-    </Reference>
     <Reference Include="System.Interactive.Async">
       <HintPath>..\packages\Ix-Async.1.2.3\lib\net45\System.Interactive.Async.dll</HintPath>
     </Reference>
     <Reference Include="System.Net" />
     <Reference Include="System.Net.Http" />
-    <Reference Include="System.Net.Http.Extensions, Version=2.2.29.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
-      <SpecificVersion>False</SpecificVersion>
-      <HintPath>..\packages\Microsoft.Net.Http.2.2.29\lib\net45\System.Net.Http.Extensions.dll</HintPath>
-    </Reference>
-    <Reference Include="System.Net.Http.Primitives, Version=4.2.29.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
-      <SpecificVersion>False</SpecificVersion>
-      <HintPath>..\packages\Microsoft.Net.Http.2.2.29\lib\net45\System.Net.Http.Primitives.dll</HintPath>
-    </Reference>
     <Reference Include="System.Net.Http.WebRequest" />
   </ItemGroup>
   <ItemGroup>
@@ -106,6 +99,7 @@
     <Compile Include="TestCredentials.cs" />
     <Compile Include="TestGrpc.cs" />
     <Compile Include="SslCredentialsTest.cs" />
+    <Compile Include="Test.cs" />
   </ItemGroup>
   <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
   <ItemGroup>
diff --git a/src/csharp/Grpc.IntegrationTesting/InteropClient.cs b/src/csharp/Grpc.IntegrationTesting/InteropClient.cs
index 24c2227..ed51af1 100644
--- a/src/csharp/Grpc.IntegrationTesting/InteropClient.cs
+++ b/src/csharp/Grpc.IntegrationTesting/InteropClient.cs
@@ -37,13 +37,12 @@
 using System.Threading;
 using System.Threading.Tasks;
 
-using Google.Apis.Auth.OAuth2;
-using Google.ProtocolBuffers;
-
-using grpc.testing;
 using Grpc.Auth;
 using Grpc.Core;
 using Grpc.Core.Utils;
+using Grpc.Testing;
+using Google.Protobuf;
+using Google.Apis.Auth.OAuth2;
 
 using NUnit.Framework;
 
@@ -183,7 +182,7 @@
         public static void RunEmptyUnary(TestService.ITestServiceClient client)
         {
             Console.WriteLine("running empty_unary");
-            var response = client.EmptyCall(Empty.DefaultInstance);
+            var response = client.EmptyCall(new Empty());
             Assert.IsNotNull(response);
             Console.WriteLine("Passed!");
         }
@@ -191,11 +190,12 @@
         public static void RunLargeUnary(TestService.ITestServiceClient client)
         {
             Console.WriteLine("running large_unary");
-            var request = SimpleRequest.CreateBuilder()
-                    .SetResponseType(PayloadType.COMPRESSABLE)
-                    .SetResponseSize(314159)
-                    .SetPayload(CreateZerosPayload(271828))
-                    .Build();
+            var request = new SimpleRequest
+            {
+                ResponseType = PayloadType.COMPRESSABLE,
+                ResponseSize = 314159,
+                Payload = CreateZerosPayload(271828)
+            };
 
             var response = client.UnaryCall(request);
 
@@ -208,7 +208,7 @@
         {
             Console.WriteLine("running client_streaming");
 
-            var bodySizes = new List<int> { 27182, 8, 1828, 45904 }.ConvertAll((size) => StreamingInputCallRequest.CreateBuilder().SetPayload(CreateZerosPayload(size)).Build());
+            var bodySizes = new List<int> { 27182, 8, 1828, 45904 }.ConvertAll((size) => new StreamingInputCallRequest { Payload = CreateZerosPayload(size) });
 
             using (var call = client.StreamingInputCall())
             {
@@ -226,11 +226,11 @@
 
             var bodySizes = new List<int> { 31415, 9, 2653, 58979 };
 
-            var request = StreamingOutputCallRequest.CreateBuilder()
-            .SetResponseType(PayloadType.COMPRESSABLE)
-            .AddRangeResponseParameters(bodySizes.ConvertAll(
-                (size) => ResponseParameters.CreateBuilder().SetSize(size).Build()))
-            .Build();
+            var request = new StreamingOutputCallRequest
+            {
+                ResponseType = PayloadType.COMPRESSABLE,
+                ResponseParameters = { bodySizes.ConvertAll((size) => new ResponseParameters { Size = size }) }
+            };
 
             using (var call = client.StreamingOutputCall(request))
             {
@@ -250,37 +250,45 @@
 
             using (var call = client.FullDuplexCall())
             {
-                await call.RequestStream.WriteAsync(StreamingOutputCallRequest.CreateBuilder()
-                .SetResponseType(PayloadType.COMPRESSABLE)
-                .AddResponseParameters(ResponseParameters.CreateBuilder().SetSize(31415))
-                .SetPayload(CreateZerosPayload(27182)).Build());
+                await call.RequestStream.WriteAsync(new StreamingOutputCallRequest
+                {
+                    ResponseType = PayloadType.COMPRESSABLE,
+                    ResponseParameters = { new ResponseParameters { Size = 31415 } },
+                    Payload = CreateZerosPayload(27182)
+                });
 
                 Assert.IsTrue(await call.ResponseStream.MoveNext());
                 Assert.AreEqual(PayloadType.COMPRESSABLE, call.ResponseStream.Current.Payload.Type);
                 Assert.AreEqual(31415, call.ResponseStream.Current.Payload.Body.Length);
 
-                await call.RequestStream.WriteAsync(StreamingOutputCallRequest.CreateBuilder()
-                            .SetResponseType(PayloadType.COMPRESSABLE)
-                            .AddResponseParameters(ResponseParameters.CreateBuilder().SetSize(9))
-                            .SetPayload(CreateZerosPayload(8)).Build());
+                await call.RequestStream.WriteAsync(new StreamingOutputCallRequest
+                {
+                    ResponseType = PayloadType.COMPRESSABLE,
+                    ResponseParameters = { new ResponseParameters { Size = 9 } },
+                    Payload = CreateZerosPayload(8)
+                });
 
                 Assert.IsTrue(await call.ResponseStream.MoveNext());
                 Assert.AreEqual(PayloadType.COMPRESSABLE, call.ResponseStream.Current.Payload.Type);
                 Assert.AreEqual(9, call.ResponseStream.Current.Payload.Body.Length);
 
-                await call.RequestStream.WriteAsync(StreamingOutputCallRequest.CreateBuilder()
-                            .SetResponseType(PayloadType.COMPRESSABLE)
-                            .AddResponseParameters(ResponseParameters.CreateBuilder().SetSize(2653))
-                            .SetPayload(CreateZerosPayload(1828)).Build());
+                await call.RequestStream.WriteAsync(new StreamingOutputCallRequest
+                {
+                    ResponseType = PayloadType.COMPRESSABLE,
+                    ResponseParameters = { new ResponseParameters { Size = 2653 } },
+                    Payload = CreateZerosPayload(1828)
+                });
 
                 Assert.IsTrue(await call.ResponseStream.MoveNext());
                 Assert.AreEqual(PayloadType.COMPRESSABLE, call.ResponseStream.Current.Payload.Type);
                 Assert.AreEqual(2653, call.ResponseStream.Current.Payload.Body.Length);
 
-                await call.RequestStream.WriteAsync(StreamingOutputCallRequest.CreateBuilder()
-                            .SetResponseType(PayloadType.COMPRESSABLE)
-                            .AddResponseParameters(ResponseParameters.CreateBuilder().SetSize(58979))
-                            .SetPayload(CreateZerosPayload(45904)).Build());
+                await call.RequestStream.WriteAsync(new StreamingOutputCallRequest
+                {
+                    ResponseType = PayloadType.COMPRESSABLE,
+                    ResponseParameters = { new ResponseParameters { Size = 58979 } },
+                    Payload = CreateZerosPayload(45904)
+                });
 
                 Assert.IsTrue(await call.ResponseStream.MoveNext());
                 Assert.AreEqual(PayloadType.COMPRESSABLE, call.ResponseStream.Current.Payload.Type);
@@ -313,13 +321,14 @@
             credential = credential.CreateScoped(new[] { AuthScope });
             client.HeaderInterceptor = AuthInterceptors.FromCredential(credential);
 
-            var request = SimpleRequest.CreateBuilder()
-                .SetResponseType(PayloadType.COMPRESSABLE)
-                    .SetResponseSize(314159)
-                    .SetPayload(CreateZerosPayload(271828))
-                    .SetFillUsername(true)
-                    .SetFillOauthScope(true)
-                    .Build();
+            var request = new SimpleRequest
+            {
+                ResponseType = PayloadType.COMPRESSABLE,
+                ResponseSize = 314159,
+                Payload = CreateZerosPayload(271828),
+                FillUsername = true,
+                FillOauthScope = true
+            };
 
             var response = client.UnaryCall(request);
 
@@ -337,13 +346,14 @@
             Assert.IsFalse(credential.IsCreateScopedRequired);
             client.HeaderInterceptor = AuthInterceptors.FromCredential(credential);
             
-            var request = SimpleRequest.CreateBuilder()
-                .SetResponseType(PayloadType.COMPRESSABLE)
-                    .SetResponseSize(314159)
-                    .SetPayload(CreateZerosPayload(271828))
-                    .SetFillUsername(true)
-                    .SetFillOauthScope(true)
-                    .Build();
+            var request = new SimpleRequest
+            {
+                ResponseType = PayloadType.COMPRESSABLE,
+                ResponseSize = 314159,
+                Payload = CreateZerosPayload(271828),
+                FillUsername = true,
+                FillOauthScope = true
+            };
 
             var response = client.UnaryCall(request);
 
@@ -362,13 +372,14 @@
             Assert.IsTrue(credential.IsCreateScopedRequired);
             client.HeaderInterceptor = AuthInterceptors.FromCredential(credential);
 
-            var request = SimpleRequest.CreateBuilder()
-                .SetResponseType(PayloadType.COMPRESSABLE)
-                    .SetResponseSize(314159)
-                    .SetPayload(CreateZerosPayload(271828))
-                    .SetFillUsername(true)
-                    .SetFillOauthScope(true)
-                    .Build();
+            var request = new SimpleRequest
+            {
+                ResponseType = PayloadType.COMPRESSABLE,
+                ResponseSize = 314159,
+                Payload = CreateZerosPayload(271828),
+                FillUsername = true,
+                FillOauthScope = true
+            };
 
             var response = client.UnaryCall(request);
 
@@ -386,10 +397,11 @@
 
             client.HeaderInterceptor = AuthInterceptors.FromAccessToken(oauth2Token);
 
-            var request = SimpleRequest.CreateBuilder()
-                .SetFillUsername(true)
-                .SetFillOauthScope(true)
-                .Build();
+            var request = new SimpleRequest
+            {
+                FillUsername = true,
+                FillOauthScope = true
+            };
 
             var response = client.UnaryCall(request);
 
@@ -406,10 +418,11 @@
             string oauth2Token = await credential.GetAccessTokenForRequestAsync();
             var headerInterceptor = AuthInterceptors.FromAccessToken(oauth2Token);
 
-            var request = SimpleRequest.CreateBuilder()
-                .SetFillUsername(true)
-                .SetFillOauthScope(true)
-                .Build();
+            var request = new SimpleRequest
+            {
+                FillUsername = true,
+                FillOauthScope = true
+            };
 
             var headers = new Metadata();
             headerInterceptor(null, "", headers);
@@ -444,10 +457,12 @@
             var cts = new CancellationTokenSource();
             using (var call = client.FullDuplexCall(cancellationToken: cts.Token))
             {
-                await call.RequestStream.WriteAsync(StreamingOutputCallRequest.CreateBuilder()
-                    .SetResponseType(PayloadType.COMPRESSABLE)
-                    .AddResponseParameters(ResponseParameters.CreateBuilder().SetSize(31415))
-                    .SetPayload(CreateZerosPayload(27182)).Build());
+                await call.RequestStream.WriteAsync(new StreamingOutputCallRequest
+                {
+                    ResponseType = PayloadType.COMPRESSABLE,
+                    ResponseParameters = { new ResponseParameters { Size = 31415 } },
+                    Payload = CreateZerosPayload(27182)
+                });
 
                 Assert.IsTrue(await call.ResponseStream.MoveNext());
                 Assert.AreEqual(PayloadType.COMPRESSABLE, call.ResponseStream.Current.Payload.Type);
@@ -470,8 +485,7 @@
             {
                 try
                 {
-                    await call.RequestStream.WriteAsync(StreamingOutputCallRequest.CreateBuilder()
-                        .SetPayload(CreateZerosPayload(27182)).Build());
+                    await call.RequestStream.WriteAsync(new StreamingOutputCallRequest { Payload = CreateZerosPayload(27182) });
                 }
                 catch (InvalidOperationException)
                 {
@@ -488,12 +502,12 @@
         public static void RunBenchmarkEmptyUnary(TestService.ITestServiceClient client)
         {
             BenchmarkUtil.RunBenchmark(10000, 10000,
-                                       () => { client.EmptyCall(Empty.DefaultInstance); });
+                                       () => { client.EmptyCall(new Empty()); });
         }
 
         private static Payload CreateZerosPayload(int size)
         {
-            return Payload.CreateBuilder().SetBody(ByteString.CopyFrom(new byte[size])).Build();
+            return new Payload { Body = ByteString.CopyFrom(new byte[size]) };
         }
 
         private static ClientOptions ParseArguments(string[] args)
diff --git a/src/csharp/Grpc.IntegrationTesting/InteropClientServerTest.cs b/src/csharp/Grpc.IntegrationTesting/InteropClientServerTest.cs
index f3158ae..7bc17a2 100644
--- a/src/csharp/Grpc.IntegrationTesting/InteropClientServerTest.cs
+++ b/src/csharp/Grpc.IntegrationTesting/InteropClientServerTest.cs
@@ -36,9 +36,9 @@
 using System.Linq;
 using System.Threading;
 using System.Threading.Tasks;
-using grpc.testing;
 using Grpc.Core;
 using Grpc.Core.Utils;
+using Grpc.Testing;
 using NUnit.Framework;
 
 namespace Grpc.IntegrationTesting
diff --git a/src/csharp/Grpc.IntegrationTesting/InteropServer.cs b/src/csharp/Grpc.IntegrationTesting/InteropServer.cs
index 0cc8b2c..718278f 100644
--- a/src/csharp/Grpc.IntegrationTesting/InteropServer.cs
+++ b/src/csharp/Grpc.IntegrationTesting/InteropServer.cs
@@ -37,10 +37,9 @@
 using System.IO;
 using System.Text.RegularExpressions;
 using System.Threading.Tasks;
-using Google.ProtocolBuffers;
-using grpc.testing;
 using Grpc.Core;
 using Grpc.Core.Utils;
+using Grpc.Testing;
 using NUnit.Framework;
 
 namespace Grpc.IntegrationTesting
diff --git a/src/csharp/Grpc.IntegrationTesting/Messages.cs b/src/csharp/Grpc.IntegrationTesting/Messages.cs
index 386f377..a3cbb7d 100644
--- a/src/csharp/Grpc.IntegrationTesting/Messages.cs
+++ b/src/csharp/Grpc.IntegrationTesting/Messages.cs
@@ -1,106 +1,58 @@
-// Generated by ProtoGen, Version=2.4.1.521, Culture=neutral, PublicKeyToken=17b3b1f090c3ea48.  DO NOT EDIT!
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: messages.proto
 #pragma warning disable 1591, 0612, 3021
 #region Designer generated code
 
-using pb = global::Google.ProtocolBuffers;
-using pbc = global::Google.ProtocolBuffers.Collections;
-using pbd = global::Google.ProtocolBuffers.Descriptors;
+using pb = global::Google.Protobuf;
+using pbc = global::Google.Protobuf.Collections;
+using pbr = global::Google.Protobuf.Reflection;
 using scg = global::System.Collections.Generic;
-namespace grpc.testing {
+namespace Grpc.Testing {
 
   [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
   public static partial class Messages {
 
-    #region Extension registration
-    public static void RegisterAllExtensions(pb::ExtensionRegistry registry) {
-    }
-    #endregion
-    #region Static variables
-    internal static pbd::MessageDescriptor internal__static_grpc_testing_Payload__Descriptor;
-    internal static pb::FieldAccess.FieldAccessorTable<global::grpc.testing.Payload, global::grpc.testing.Payload.Builder> internal__static_grpc_testing_Payload__FieldAccessorTable;
-    internal static pbd::MessageDescriptor internal__static_grpc_testing_SimpleRequest__Descriptor;
-    internal static pb::FieldAccess.FieldAccessorTable<global::grpc.testing.SimpleRequest, global::grpc.testing.SimpleRequest.Builder> internal__static_grpc_testing_SimpleRequest__FieldAccessorTable;
-    internal static pbd::MessageDescriptor internal__static_grpc_testing_SimpleResponse__Descriptor;
-    internal static pb::FieldAccess.FieldAccessorTable<global::grpc.testing.SimpleResponse, global::grpc.testing.SimpleResponse.Builder> internal__static_grpc_testing_SimpleResponse__FieldAccessorTable;
-    internal static pbd::MessageDescriptor internal__static_grpc_testing_StreamingInputCallRequest__Descriptor;
-    internal static pb::FieldAccess.FieldAccessorTable<global::grpc.testing.StreamingInputCallRequest, global::grpc.testing.StreamingInputCallRequest.Builder> internal__static_grpc_testing_StreamingInputCallRequest__FieldAccessorTable;
-    internal static pbd::MessageDescriptor internal__static_grpc_testing_StreamingInputCallResponse__Descriptor;
-    internal static pb::FieldAccess.FieldAccessorTable<global::grpc.testing.StreamingInputCallResponse, global::grpc.testing.StreamingInputCallResponse.Builder> internal__static_grpc_testing_StreamingInputCallResponse__FieldAccessorTable;
-    internal static pbd::MessageDescriptor internal__static_grpc_testing_ResponseParameters__Descriptor;
-    internal static pb::FieldAccess.FieldAccessorTable<global::grpc.testing.ResponseParameters, global::grpc.testing.ResponseParameters.Builder> internal__static_grpc_testing_ResponseParameters__FieldAccessorTable;
-    internal static pbd::MessageDescriptor internal__static_grpc_testing_StreamingOutputCallRequest__Descriptor;
-    internal static pb::FieldAccess.FieldAccessorTable<global::grpc.testing.StreamingOutputCallRequest, global::grpc.testing.StreamingOutputCallRequest.Builder> internal__static_grpc_testing_StreamingOutputCallRequest__FieldAccessorTable;
-    internal static pbd::MessageDescriptor internal__static_grpc_testing_StreamingOutputCallResponse__Descriptor;
-    internal static pb::FieldAccess.FieldAccessorTable<global::grpc.testing.StreamingOutputCallResponse, global::grpc.testing.StreamingOutputCallResponse.Builder> internal__static_grpc_testing_StreamingOutputCallResponse__FieldAccessorTable;
-    #endregion
     #region Descriptor
-    public static pbd::FileDescriptor Descriptor {
+    public static pbr::FileDescriptor Descriptor {
       get { return descriptor; }
     }
-    private static pbd::FileDescriptor descriptor;
+    private static pbr::FileDescriptor descriptor;
 
     static Messages() {
       byte[] descriptorData = global::System.Convert.FromBase64String(
           string.Concat(
-            "Cg5tZXNzYWdlcy5wcm90bxIMZ3JwYy50ZXN0aW5nIkAKB1BheWxvYWQSJwoE",
-            "dHlwZRgBIAEoDjIZLmdycGMudGVzdGluZy5QYXlsb2FkVHlwZRIMCgRib2R5",
-            "GAIgASgMIrEBCg1TaW1wbGVSZXF1ZXN0EjAKDXJlc3BvbnNlX3R5cGUYASAB",
-            "KA4yGS5ncnBjLnRlc3RpbmcuUGF5bG9hZFR5cGUSFQoNcmVzcG9uc2Vfc2l6",
-            "ZRgCIAEoBRImCgdwYXlsb2FkGAMgASgLMhUuZ3JwYy50ZXN0aW5nLlBheWxv",
-            "YWQSFQoNZmlsbF91c2VybmFtZRgEIAEoCBIYChBmaWxsX29hdXRoX3Njb3Bl",
-            "GAUgASgIIl8KDlNpbXBsZVJlc3BvbnNlEiYKB3BheWxvYWQYASABKAsyFS5n",
-            "cnBjLnRlc3RpbmcuUGF5bG9hZBIQCgh1c2VybmFtZRgCIAEoCRITCgtvYXV0",
-            "aF9zY29wZRgDIAEoCSJDChlTdHJlYW1pbmdJbnB1dENhbGxSZXF1ZXN0EiYK",
-            "B3BheWxvYWQYASABKAsyFS5ncnBjLnRlc3RpbmcuUGF5bG9hZCI9ChpTdHJl",
-            "YW1pbmdJbnB1dENhbGxSZXNwb25zZRIfChdhZ2dyZWdhdGVkX3BheWxvYWRf",
-            "c2l6ZRgBIAEoBSI3ChJSZXNwb25zZVBhcmFtZXRlcnMSDAoEc2l6ZRgBIAEo",
-            "BRITCgtpbnRlcnZhbF91cxgCIAEoBSK1AQoaU3RyZWFtaW5nT3V0cHV0Q2Fs",
-            "bFJlcXVlc3QSMAoNcmVzcG9uc2VfdHlwZRgBIAEoDjIZLmdycGMudGVzdGlu",
-            "Zy5QYXlsb2FkVHlwZRI9ChNyZXNwb25zZV9wYXJhbWV0ZXJzGAIgAygLMiAu",
-            "Z3JwYy50ZXN0aW5nLlJlc3BvbnNlUGFyYW1ldGVycxImCgdwYXlsb2FkGAMg",
-            "ASgLMhUuZ3JwYy50ZXN0aW5nLlBheWxvYWQiRQobU3RyZWFtaW5nT3V0cHV0",
-            "Q2FsbFJlc3BvbnNlEiYKB3BheWxvYWQYASABKAsyFS5ncnBjLnRlc3Rpbmcu",
-            "UGF5bG9hZCo/CgtQYXlsb2FkVHlwZRIQCgxDT01QUkVTU0FCTEUQABISCg5V",
-          "TkNPTVBSRVNTQUJMRRABEgoKBlJBTkRPTRAC"));
-      pbd::FileDescriptor.InternalDescriptorAssigner assigner = delegate(pbd::FileDescriptor root) {
-        descriptor = root;
-        internal__static_grpc_testing_Payload__Descriptor = Descriptor.MessageTypes[0];
-        internal__static_grpc_testing_Payload__FieldAccessorTable =
-            new pb::FieldAccess.FieldAccessorTable<global::grpc.testing.Payload, global::grpc.testing.Payload.Builder>(internal__static_grpc_testing_Payload__Descriptor,
-                new string[] { "Type", "Body", });
-        internal__static_grpc_testing_SimpleRequest__Descriptor = Descriptor.MessageTypes[1];
-        internal__static_grpc_testing_SimpleRequest__FieldAccessorTable =
-            new pb::FieldAccess.FieldAccessorTable<global::grpc.testing.SimpleRequest, global::grpc.testing.SimpleRequest.Builder>(internal__static_grpc_testing_SimpleRequest__Descriptor,
-                new string[] { "ResponseType", "ResponseSize", "Payload", "FillUsername", "FillOauthScope", });
-        internal__static_grpc_testing_SimpleResponse__Descriptor = Descriptor.MessageTypes[2];
-        internal__static_grpc_testing_SimpleResponse__FieldAccessorTable =
-            new pb::FieldAccess.FieldAccessorTable<global::grpc.testing.SimpleResponse, global::grpc.testing.SimpleResponse.Builder>(internal__static_grpc_testing_SimpleResponse__Descriptor,
-                new string[] { "Payload", "Username", "OauthScope", });
-        internal__static_grpc_testing_StreamingInputCallRequest__Descriptor = Descriptor.MessageTypes[3];
-        internal__static_grpc_testing_StreamingInputCallRequest__FieldAccessorTable =
-            new pb::FieldAccess.FieldAccessorTable<global::grpc.testing.StreamingInputCallRequest, global::grpc.testing.StreamingInputCallRequest.Builder>(internal__static_grpc_testing_StreamingInputCallRequest__Descriptor,
-                new string[] { "Payload", });
-        internal__static_grpc_testing_StreamingInputCallResponse__Descriptor = Descriptor.MessageTypes[4];
-        internal__static_grpc_testing_StreamingInputCallResponse__FieldAccessorTable =
-            new pb::FieldAccess.FieldAccessorTable<global::grpc.testing.StreamingInputCallResponse, global::grpc.testing.StreamingInputCallResponse.Builder>(internal__static_grpc_testing_StreamingInputCallResponse__Descriptor,
-                new string[] { "AggregatedPayloadSize", });
-        internal__static_grpc_testing_ResponseParameters__Descriptor = Descriptor.MessageTypes[5];
-        internal__static_grpc_testing_ResponseParameters__FieldAccessorTable =
-            new pb::FieldAccess.FieldAccessorTable<global::grpc.testing.ResponseParameters, global::grpc.testing.ResponseParameters.Builder>(internal__static_grpc_testing_ResponseParameters__Descriptor,
-                new string[] { "Size", "IntervalUs", });
-        internal__static_grpc_testing_StreamingOutputCallRequest__Descriptor = Descriptor.MessageTypes[6];
-        internal__static_grpc_testing_StreamingOutputCallRequest__FieldAccessorTable =
-            new pb::FieldAccess.FieldAccessorTable<global::grpc.testing.StreamingOutputCallRequest, global::grpc.testing.StreamingOutputCallRequest.Builder>(internal__static_grpc_testing_StreamingOutputCallRequest__Descriptor,
-                new string[] { "ResponseType", "ResponseParameters", "Payload", });
-        internal__static_grpc_testing_StreamingOutputCallResponse__Descriptor = Descriptor.MessageTypes[7];
-        internal__static_grpc_testing_StreamingOutputCallResponse__FieldAccessorTable =
-            new pb::FieldAccess.FieldAccessorTable<global::grpc.testing.StreamingOutputCallResponse, global::grpc.testing.StreamingOutputCallResponse.Builder>(internal__static_grpc_testing_StreamingOutputCallResponse__Descriptor,
-                new string[] { "Payload", });
-        return null;
-      };
-      pbd::FileDescriptor.InternalBuildGeneratedFileFrom(descriptorData,
-          new pbd::FileDescriptor[] {
-          }, assigner);
+            "Cg5tZXNzYWdlcy5wcm90bxIMZ3JwYy50ZXN0aW5nIkAKB1BheWxvYWQSJwoE", 
+            "dHlwZRgBIAEoDjIZLmdycGMudGVzdGluZy5QYXlsb2FkVHlwZRIMCgRib2R5", 
+            "GAIgASgMIrEBCg1TaW1wbGVSZXF1ZXN0EjAKDXJlc3BvbnNlX3R5cGUYASAB", 
+            "KA4yGS5ncnBjLnRlc3RpbmcuUGF5bG9hZFR5cGUSFQoNcmVzcG9uc2Vfc2l6", 
+            "ZRgCIAEoBRImCgdwYXlsb2FkGAMgASgLMhUuZ3JwYy50ZXN0aW5nLlBheWxv", 
+            "YWQSFQoNZmlsbF91c2VybmFtZRgEIAEoCBIYChBmaWxsX29hdXRoX3Njb3Bl", 
+            "GAUgASgIIl8KDlNpbXBsZVJlc3BvbnNlEiYKB3BheWxvYWQYASABKAsyFS5n", 
+            "cnBjLnRlc3RpbmcuUGF5bG9hZBIQCgh1c2VybmFtZRgCIAEoCRITCgtvYXV0", 
+            "aF9zY29wZRgDIAEoCSJDChlTdHJlYW1pbmdJbnB1dENhbGxSZXF1ZXN0EiYK", 
+            "B3BheWxvYWQYASABKAsyFS5ncnBjLnRlc3RpbmcuUGF5bG9hZCI9ChpTdHJl", 
+            "YW1pbmdJbnB1dENhbGxSZXNwb25zZRIfChdhZ2dyZWdhdGVkX3BheWxvYWRf", 
+            "c2l6ZRgBIAEoBSI3ChJSZXNwb25zZVBhcmFtZXRlcnMSDAoEc2l6ZRgBIAEo", 
+            "BRITCgtpbnRlcnZhbF91cxgCIAEoBSK1AQoaU3RyZWFtaW5nT3V0cHV0Q2Fs", 
+            "bFJlcXVlc3QSMAoNcmVzcG9uc2VfdHlwZRgBIAEoDjIZLmdycGMudGVzdGlu", 
+            "Zy5QYXlsb2FkVHlwZRI9ChNyZXNwb25zZV9wYXJhbWV0ZXJzGAIgAygLMiAu", 
+            "Z3JwYy50ZXN0aW5nLlJlc3BvbnNlUGFyYW1ldGVycxImCgdwYXlsb2FkGAMg", 
+            "ASgLMhUuZ3JwYy50ZXN0aW5nLlBheWxvYWQiRQobU3RyZWFtaW5nT3V0cHV0", 
+            "Q2FsbFJlc3BvbnNlEiYKB3BheWxvYWQYASABKAsyFS5ncnBjLnRlc3Rpbmcu", 
+            "UGF5bG9hZCo/CgtQYXlsb2FkVHlwZRIQCgxDT01QUkVTU0FCTEUQABISCg5V", 
+            "TkNPTVBSRVNTQUJMRRABEgoKBlJBTkRPTRACYgZwcm90bzM="));
+      descriptor = pbr::FileDescriptor.InternalBuildGeneratedFileFrom(descriptorData,
+          new pbr::FileDescriptor[] { },
+          new pbr::GeneratedCodeInfo(new[] {typeof(global::Grpc.Testing.PayloadType), }, new pbr::GeneratedCodeInfo[] {
+            new pbr::GeneratedCodeInfo(typeof(global::Grpc.Testing.Payload), new[]{ "Type", "Body" }, null, null, null),
+            new pbr::GeneratedCodeInfo(typeof(global::Grpc.Testing.SimpleRequest), new[]{ "ResponseType", "ResponseSize", "Payload", "FillUsername", "FillOauthScope" }, null, null, null),
+            new pbr::GeneratedCodeInfo(typeof(global::Grpc.Testing.SimpleResponse), new[]{ "Payload", "Username", "OauthScope" }, null, null, null),
+            new pbr::GeneratedCodeInfo(typeof(global::Grpc.Testing.StreamingInputCallRequest), new[]{ "Payload" }, null, null, null),
+            new pbr::GeneratedCodeInfo(typeof(global::Grpc.Testing.StreamingInputCallResponse), new[]{ "AggregatedPayloadSize" }, null, null, null),
+            new pbr::GeneratedCodeInfo(typeof(global::Grpc.Testing.ResponseParameters), new[]{ "Size", "IntervalUs" }, null, null, null),
+            new pbr::GeneratedCodeInfo(typeof(global::Grpc.Testing.StreamingOutputCallRequest), new[]{ "ResponseType", "ResponseParameters", "Payload" }, null, null, null),
+            new pbr::GeneratedCodeInfo(typeof(global::Grpc.Testing.StreamingOutputCallResponse), new[]{ "Payload" }, null, null, null)
+          }));
     }
     #endregion
 
@@ -116,2772 +68,1101 @@
 
   #region Messages
   [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
-  public sealed partial class Payload : pb::GeneratedMessage<Payload, Payload.Builder> {
-    private Payload() { }
-    private static readonly Payload defaultInstance = new Payload().MakeReadOnly();
-    private static readonly string[] _payloadFieldNames = new string[] { "body", "type" };
-    private static readonly uint[] _payloadFieldTags = new uint[] { 18, 8 };
-    public static Payload DefaultInstance {
-      get { return defaultInstance; }
+  public sealed partial class Payload : pb::IMessage<Payload> {
+    private static readonly pb::MessageParser<Payload> _parser = new pb::MessageParser<Payload>(() => new Payload());
+    public static pb::MessageParser<Payload> Parser { get { return _parser; } }
+
+    public static pbr::MessageDescriptor Descriptor {
+      get { return global::Grpc.Testing.Messages.Descriptor.MessageTypes[0]; }
     }
 
-    public override Payload DefaultInstanceForType {
-      get { return DefaultInstance; }
+    pbr::MessageDescriptor pb::IMessage.Descriptor {
+      get { return Descriptor; }
     }
 
-    protected override Payload ThisMessage {
-      get { return this; }
+    public Payload() {
+      OnConstruction();
     }
 
-    public static pbd::MessageDescriptor Descriptor {
-      get { return global::grpc.testing.Messages.internal__static_grpc_testing_Payload__Descriptor; }
+    partial void OnConstruction();
+
+    public Payload(Payload other) : this() {
+      type_ = other.type_;
+      body_ = other.body_;
     }
 
-    protected override pb::FieldAccess.FieldAccessorTable<Payload, Payload.Builder> InternalFieldAccessors {
-      get { return global::grpc.testing.Messages.internal__static_grpc_testing_Payload__FieldAccessorTable; }
+    public Payload Clone() {
+      return new Payload(this);
     }
 
     public const int TypeFieldNumber = 1;
-    private bool hasType;
-    private global::grpc.testing.PayloadType type_ = global::grpc.testing.PayloadType.COMPRESSABLE;
-    public bool HasType {
-      get { return hasType; }
-    }
-    public global::grpc.testing.PayloadType Type {
+    private global::Grpc.Testing.PayloadType type_ = global::Grpc.Testing.PayloadType.COMPRESSABLE;
+    public global::Grpc.Testing.PayloadType Type {
       get { return type_; }
+      set {
+        type_ = value;
+      }
     }
 
     public const int BodyFieldNumber = 2;
-    private bool hasBody;
     private pb::ByteString body_ = pb::ByteString.Empty;
-    public bool HasBody {
-      get { return hasBody; }
-    }
     public pb::ByteString Body {
       get { return body_; }
+      set {
+        body_ = pb::Preconditions.CheckNotNull(value, "value");
+      }
     }
 
-    public override bool IsInitialized {
-      get {
+    public override bool Equals(object other) {
+      return Equals(other as Payload);
+    }
+
+    public bool Equals(Payload other) {
+      if (ReferenceEquals(other, null)) {
+        return false;
+      }
+      if (ReferenceEquals(other, this)) {
         return true;
       }
+      if (Type != other.Type) return false;
+      if (Body != other.Body) return false;
+      return true;
     }
 
-    public override void WriteTo(pb::ICodedOutputStream output) {
-      int size = SerializedSize;
-      string[] field_names = _payloadFieldNames;
-      if (hasType) {
-        output.WriteEnum(1, field_names[1], (int) Type, Type);
-      }
-      if (hasBody) {
-        output.WriteBytes(2, field_names[0], Body);
-      }
-      UnknownFields.WriteTo(output);
+    public override int GetHashCode() {
+      int hash = 1;
+      if (Type != global::Grpc.Testing.PayloadType.COMPRESSABLE) hash ^= Type.GetHashCode();
+      if (Body.Length != 0) hash ^= Body.GetHashCode();
+      return hash;
     }
 
-    private int memoizedSerializedSize = -1;
-    public override int SerializedSize {
-      get {
-        int size = memoizedSerializedSize;
-        if (size != -1) return size;
+    public override string ToString() {
+      return pb::JsonFormatter.Default.Format(this);
+    }
 
-        size = 0;
-        if (hasType) {
-          size += pb::CodedOutputStream.ComputeEnumSize(1, (int) Type);
-        }
-        if (hasBody) {
-          size += pb::CodedOutputStream.ComputeBytesSize(2, Body);
-        }
-        size += UnknownFields.SerializedSize;
-        memoizedSerializedSize = size;
-        return size;
+    public void WriteTo(pb::CodedOutputStream output) {
+      if (Type != global::Grpc.Testing.PayloadType.COMPRESSABLE) {
+        output.WriteRawTag(8);
+        output.WriteEnum((int) Type);
+      }
+      if (Body.Length != 0) {
+        output.WriteRawTag(18);
+        output.WriteBytes(Body);
       }
     }
 
-    public static Payload ParseFrom(pb::ByteString data) {
-      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
-    }
-    public static Payload ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
-      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
-    }
-    public static Payload ParseFrom(byte[] data) {
-      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
-    }
-    public static Payload ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
-      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
-    }
-    public static Payload ParseFrom(global::System.IO.Stream input) {
-      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
-    }
-    public static Payload ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
-      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
-    }
-    public static Payload ParseDelimitedFrom(global::System.IO.Stream input) {
-      return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
-    }
-    public static Payload ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
-      return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
-    }
-    public static Payload ParseFrom(pb::ICodedInputStream input) {
-      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
-    }
-    public static Payload ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
-      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
-    }
-    private Payload MakeReadOnly() {
-      return this;
+    public int CalculateSize() {
+      int size = 0;
+      if (Type != global::Grpc.Testing.PayloadType.COMPRESSABLE) {
+        size += 1 + pb::CodedOutputStream.ComputeEnumSize((int) Type);
+      }
+      if (Body.Length != 0) {
+        size += 1 + pb::CodedOutputStream.ComputeBytesSize(Body);
+      }
+      return size;
     }
 
-    public static Builder CreateBuilder() { return new Builder(); }
-    public override Builder ToBuilder() { return CreateBuilder(this); }
-    public override Builder CreateBuilderForType() { return new Builder(); }
-    public static Builder CreateBuilder(Payload prototype) {
-      return new Builder(prototype);
+    public void MergeFrom(Payload other) {
+      if (other == null) {
+        return;
+      }
+      if (other.Type != global::Grpc.Testing.PayloadType.COMPRESSABLE) {
+        Type = other.Type;
+      }
+      if (other.Body.Length != 0) {
+        Body = other.Body;
+      }
     }
 
-    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
-    public sealed partial class Builder : pb::GeneratedBuilder<Payload, Builder> {
-      protected override Builder ThisBuilder {
-        get { return this; }
-      }
-      public Builder() {
-        result = DefaultInstance;
-        resultIsReadOnly = true;
-      }
-      internal Builder(Payload cloneFrom) {
-        result = cloneFrom;
-        resultIsReadOnly = true;
-      }
-
-      private bool resultIsReadOnly;
-      private Payload result;
-
-      private Payload PrepareBuilder() {
-        if (resultIsReadOnly) {
-          Payload original = result;
-          result = new Payload();
-          resultIsReadOnly = false;
-          MergeFrom(original);
-        }
-        return result;
-      }
-
-      public override bool IsInitialized {
-        get { return result.IsInitialized; }
-      }
-
-      protected override Payload MessageBeingBuilt {
-        get { return PrepareBuilder(); }
-      }
-
-      public override Builder Clear() {
-        result = DefaultInstance;
-        resultIsReadOnly = true;
-        return this;
-      }
-
-      public override Builder Clone() {
-        if (resultIsReadOnly) {
-          return new Builder(result);
-        } else {
-          return new Builder().MergeFrom(result);
-        }
-      }
-
-      public override pbd::MessageDescriptor DescriptorForType {
-        get { return global::grpc.testing.Payload.Descriptor; }
-      }
-
-      public override Payload DefaultInstanceForType {
-        get { return global::grpc.testing.Payload.DefaultInstance; }
-      }
-
-      public override Payload BuildPartial() {
-        if (resultIsReadOnly) {
-          return result;
-        }
-        resultIsReadOnly = true;
-        return result.MakeReadOnly();
-      }
-
-      public override Builder MergeFrom(pb::IMessage other) {
-        if (other is Payload) {
-          return MergeFrom((Payload) other);
-        } else {
-          base.MergeFrom(other);
-          return this;
-        }
-      }
-
-      public override Builder MergeFrom(Payload other) {
-        if (other == global::grpc.testing.Payload.DefaultInstance) return this;
-        PrepareBuilder();
-        if (other.HasType) {
-          Type = other.Type;
-        }
-        if (other.HasBody) {
-          Body = other.Body;
-        }
-        this.MergeUnknownFields(other.UnknownFields);
-        return this;
-      }
-
-      public override Builder MergeFrom(pb::ICodedInputStream input) {
-        return MergeFrom(input, pb::ExtensionRegistry.Empty);
-      }
-
-      public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
-        PrepareBuilder();
-        pb::UnknownFieldSet.Builder unknownFields = null;
-        uint tag;
-        string field_name;
-        while (input.ReadTag(out tag, out field_name)) {
-          if(tag == 0 && field_name != null) {
-            int field_ordinal = global::System.Array.BinarySearch(_payloadFieldNames, field_name, global::System.StringComparer.Ordinal);
-            if(field_ordinal >= 0)
-              tag = _payloadFieldTags[field_ordinal];
-            else {
-              if (unknownFields == null) {
-                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
-              }
-              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);
-              continue;
-            }
+    public void MergeFrom(pb::CodedInputStream input) {
+      uint tag;
+      while ((tag = input.ReadTag()) != 0) {
+        switch(tag) {
+          default:
+            input.SkipLastField();
+            break;
+          case 8: {
+            type_ = (global::Grpc.Testing.PayloadType) input.ReadEnum();
+            break;
           }
-          switch (tag) {
-            case 0: {
-              throw pb::InvalidProtocolBufferException.InvalidTag();
-            }
-            default: {
-              if (pb::WireFormat.IsEndGroupTag(tag)) {
-                if (unknownFields != null) {
-                  this.UnknownFields = unknownFields.Build();
-                }
-                return this;
-              }
-              if (unknownFields == null) {
-                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
-              }
-              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);
-              break;
-            }
-            case 8: {
-              object unknown;
-              if(input.ReadEnum(ref result.type_, out unknown)) {
-                result.hasType = true;
-              } else if(unknown is int) {
-                if (unknownFields == null) {
-                  unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
-                }
-                unknownFields.MergeVarintField(1, (ulong)(int)unknown);
-              }
-              break;
-            }
-            case 18: {
-              result.hasBody = input.ReadBytes(ref result.body_);
-              break;
-            }
+          case 18: {
+            Body = input.ReadBytes();
+            break;
           }
         }
-
-        if (unknownFields != null) {
-          this.UnknownFields = unknownFields.Build();
-        }
-        return this;
-      }
-
-
-      public bool HasType {
-       get { return result.hasType; }
-      }
-      public global::grpc.testing.PayloadType Type {
-        get { return result.Type; }
-        set { SetType(value); }
-      }
-      public Builder SetType(global::grpc.testing.PayloadType value) {
-        PrepareBuilder();
-        result.hasType = true;
-        result.type_ = value;
-        return this;
-      }
-      public Builder ClearType() {
-        PrepareBuilder();
-        result.hasType = false;
-        result.type_ = global::grpc.testing.PayloadType.COMPRESSABLE;
-        return this;
-      }
-
-      public bool HasBody {
-        get { return result.hasBody; }
-      }
-      public pb::ByteString Body {
-        get { return result.Body; }
-        set { SetBody(value); }
-      }
-      public Builder SetBody(pb::ByteString value) {
-        pb::ThrowHelper.ThrowIfNull(value, "value");
-        PrepareBuilder();
-        result.hasBody = true;
-        result.body_ = value;
-        return this;
-      }
-      public Builder ClearBody() {
-        PrepareBuilder();
-        result.hasBody = false;
-        result.body_ = pb::ByteString.Empty;
-        return this;
       }
     }
-    static Payload() {
-      object.ReferenceEquals(global::grpc.testing.Messages.Descriptor, null);
-    }
+
   }
 
   [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
-  public sealed partial class SimpleRequest : pb::GeneratedMessage<SimpleRequest, SimpleRequest.Builder> {
-    private SimpleRequest() { }
-    private static readonly SimpleRequest defaultInstance = new SimpleRequest().MakeReadOnly();
-    private static readonly string[] _simpleRequestFieldNames = new string[] { "fill_oauth_scope", "fill_username", "payload", "response_size", "response_type" };
-    private static readonly uint[] _simpleRequestFieldTags = new uint[] { 40, 32, 26, 16, 8 };
-    public static SimpleRequest DefaultInstance {
-      get { return defaultInstance; }
+  public sealed partial class SimpleRequest : pb::IMessage<SimpleRequest> {
+    private static readonly pb::MessageParser<SimpleRequest> _parser = new pb::MessageParser<SimpleRequest>(() => new SimpleRequest());
+    public static pb::MessageParser<SimpleRequest> Parser { get { return _parser; } }
+
+    public static pbr::MessageDescriptor Descriptor {
+      get { return global::Grpc.Testing.Messages.Descriptor.MessageTypes[1]; }
     }
 
-    public override SimpleRequest DefaultInstanceForType {
-      get { return DefaultInstance; }
+    pbr::MessageDescriptor pb::IMessage.Descriptor {
+      get { return Descriptor; }
     }
 
-    protected override SimpleRequest ThisMessage {
-      get { return this; }
+    public SimpleRequest() {
+      OnConstruction();
     }
 
-    public static pbd::MessageDescriptor Descriptor {
-      get { return global::grpc.testing.Messages.internal__static_grpc_testing_SimpleRequest__Descriptor; }
+    partial void OnConstruction();
+
+    public SimpleRequest(SimpleRequest other) : this() {
+      responseType_ = other.responseType_;
+      responseSize_ = other.responseSize_;
+      Payload = other.payload_ != null ? other.Payload.Clone() : null;
+      fillUsername_ = other.fillUsername_;
+      fillOauthScope_ = other.fillOauthScope_;
     }
 
-    protected override pb::FieldAccess.FieldAccessorTable<SimpleRequest, SimpleRequest.Builder> InternalFieldAccessors {
-      get { return global::grpc.testing.Messages.internal__static_grpc_testing_SimpleRequest__FieldAccessorTable; }
+    public SimpleRequest Clone() {
+      return new SimpleRequest(this);
     }
 
     public const int ResponseTypeFieldNumber = 1;
-    private bool hasResponseType;
-    private global::grpc.testing.PayloadType responseType_ = global::grpc.testing.PayloadType.COMPRESSABLE;
-    public bool HasResponseType {
-      get { return hasResponseType; }
-    }
-    public global::grpc.testing.PayloadType ResponseType {
+    private global::Grpc.Testing.PayloadType responseType_ = global::Grpc.Testing.PayloadType.COMPRESSABLE;
+    public global::Grpc.Testing.PayloadType ResponseType {
       get { return responseType_; }
+      set {
+        responseType_ = value;
+      }
     }
 
     public const int ResponseSizeFieldNumber = 2;
-    private bool hasResponseSize;
     private int responseSize_;
-    public bool HasResponseSize {
-      get { return hasResponseSize; }
-    }
     public int ResponseSize {
       get { return responseSize_; }
+      set {
+        responseSize_ = value;
+      }
     }
 
     public const int PayloadFieldNumber = 3;
-    private bool hasPayload;
-    private global::grpc.testing.Payload payload_;
-    public bool HasPayload {
-      get { return hasPayload; }
-    }
-    public global::grpc.testing.Payload Payload {
-      get { return payload_ ?? global::grpc.testing.Payload.DefaultInstance; }
+    private global::Grpc.Testing.Payload payload_;
+    public global::Grpc.Testing.Payload Payload {
+      get { return payload_; }
+      set {
+        payload_ = value;
+      }
     }
 
     public const int FillUsernameFieldNumber = 4;
-    private bool hasFillUsername;
     private bool fillUsername_;
-    public bool HasFillUsername {
-      get { return hasFillUsername; }
-    }
     public bool FillUsername {
       get { return fillUsername_; }
+      set {
+        fillUsername_ = value;
+      }
     }
 
     public const int FillOauthScopeFieldNumber = 5;
-    private bool hasFillOauthScope;
     private bool fillOauthScope_;
-    public bool HasFillOauthScope {
-      get { return hasFillOauthScope; }
-    }
     public bool FillOauthScope {
       get { return fillOauthScope_; }
+      set {
+        fillOauthScope_ = value;
+      }
     }
 
-    public override bool IsInitialized {
-      get {
+    public override bool Equals(object other) {
+      return Equals(other as SimpleRequest);
+    }
+
+    public bool Equals(SimpleRequest other) {
+      if (ReferenceEquals(other, null)) {
+        return false;
+      }
+      if (ReferenceEquals(other, this)) {
         return true;
       }
+      if (ResponseType != other.ResponseType) return false;
+      if (ResponseSize != other.ResponseSize) return false;
+      if (!object.Equals(Payload, other.Payload)) return false;
+      if (FillUsername != other.FillUsername) return false;
+      if (FillOauthScope != other.FillOauthScope) return false;
+      return true;
     }
 
-    public override void WriteTo(pb::ICodedOutputStream output) {
-      int size = SerializedSize;
-      string[] field_names = _simpleRequestFieldNames;
-      if (hasResponseType) {
-        output.WriteEnum(1, field_names[4], (int) ResponseType, ResponseType);
-      }
-      if (hasResponseSize) {
-        output.WriteInt32(2, field_names[3], ResponseSize);
-      }
-      if (hasPayload) {
-        output.WriteMessage(3, field_names[2], Payload);
-      }
-      if (hasFillUsername) {
-        output.WriteBool(4, field_names[1], FillUsername);
-      }
-      if (hasFillOauthScope) {
-        output.WriteBool(5, field_names[0], FillOauthScope);
-      }
-      UnknownFields.WriteTo(output);
+    public override int GetHashCode() {
+      int hash = 1;
+      if (ResponseType != global::Grpc.Testing.PayloadType.COMPRESSABLE) hash ^= ResponseType.GetHashCode();
+      if (ResponseSize != 0) hash ^= ResponseSize.GetHashCode();
+      if (payload_ != null) hash ^= Payload.GetHashCode();
+      if (FillUsername != false) hash ^= FillUsername.GetHashCode();
+      if (FillOauthScope != false) hash ^= FillOauthScope.GetHashCode();
+      return hash;
     }
 
-    private int memoizedSerializedSize = -1;
-    public override int SerializedSize {
-      get {
-        int size = memoizedSerializedSize;
-        if (size != -1) return size;
+    public override string ToString() {
+      return pb::JsonFormatter.Default.Format(this);
+    }
 
-        size = 0;
-        if (hasResponseType) {
-          size += pb::CodedOutputStream.ComputeEnumSize(1, (int) ResponseType);
+    public void WriteTo(pb::CodedOutputStream output) {
+      if (ResponseType != global::Grpc.Testing.PayloadType.COMPRESSABLE) {
+        output.WriteRawTag(8);
+        output.WriteEnum((int) ResponseType);
+      }
+      if (ResponseSize != 0) {
+        output.WriteRawTag(16);
+        output.WriteInt32(ResponseSize);
+      }
+      if (payload_ != null) {
+        output.WriteRawTag(26);
+        output.WriteMessage(Payload);
+      }
+      if (FillUsername != false) {
+        output.WriteRawTag(32);
+        output.WriteBool(FillUsername);
+      }
+      if (FillOauthScope != false) {
+        output.WriteRawTag(40);
+        output.WriteBool(FillOauthScope);
+      }
+    }
+
+    public int CalculateSize() {
+      int size = 0;
+      if (ResponseType != global::Grpc.Testing.PayloadType.COMPRESSABLE) {
+        size += 1 + pb::CodedOutputStream.ComputeEnumSize((int) ResponseType);
+      }
+      if (ResponseSize != 0) {
+        size += 1 + pb::CodedOutputStream.ComputeInt32Size(ResponseSize);
+      }
+      if (payload_ != null) {
+        size += 1 + pb::CodedOutputStream.ComputeMessageSize(Payload);
+      }
+      if (FillUsername != false) {
+        size += 1 + 1;
+      }
+      if (FillOauthScope != false) {
+        size += 1 + 1;
+      }
+      return size;
+    }
+
+    public void MergeFrom(SimpleRequest other) {
+      if (other == null) {
+        return;
+      }
+      if (other.ResponseType != global::Grpc.Testing.PayloadType.COMPRESSABLE) {
+        ResponseType = other.ResponseType;
+      }
+      if (other.ResponseSize != 0) {
+        ResponseSize = other.ResponseSize;
+      }
+      if (other.payload_ != null) {
+        if (payload_ == null) {
+          payload_ = new global::Grpc.Testing.Payload();
         }
-        if (hasResponseSize) {
-          size += pb::CodedOutputStream.ComputeInt32Size(2, ResponseSize);
-        }
-        if (hasPayload) {
-          size += pb::CodedOutputStream.ComputeMessageSize(3, Payload);
-        }
-        if (hasFillUsername) {
-          size += pb::CodedOutputStream.ComputeBoolSize(4, FillUsername);
-        }
-        if (hasFillOauthScope) {
-          size += pb::CodedOutputStream.ComputeBoolSize(5, FillOauthScope);
-        }
-        size += UnknownFields.SerializedSize;
-        memoizedSerializedSize = size;
-        return size;
+        Payload.MergeFrom(other.Payload);
+      }
+      if (other.FillUsername != false) {
+        FillUsername = other.FillUsername;
+      }
+      if (other.FillOauthScope != false) {
+        FillOauthScope = other.FillOauthScope;
       }
     }
 
-    public static SimpleRequest ParseFrom(pb::ByteString data) {
-      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
-    }
-    public static SimpleRequest ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
-      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
-    }
-    public static SimpleRequest ParseFrom(byte[] data) {
-      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
-    }
-    public static SimpleRequest ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
-      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
-    }
-    public static SimpleRequest ParseFrom(global::System.IO.Stream input) {
-      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
-    }
-    public static SimpleRequest ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
-      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
-    }
-    public static SimpleRequest ParseDelimitedFrom(global::System.IO.Stream input) {
-      return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
-    }
-    public static SimpleRequest ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
-      return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
-    }
-    public static SimpleRequest ParseFrom(pb::ICodedInputStream input) {
-      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
-    }
-    public static SimpleRequest ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
-      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
-    }
-    private SimpleRequest MakeReadOnly() {
-      return this;
-    }
-
-    public static Builder CreateBuilder() { return new Builder(); }
-    public override Builder ToBuilder() { return CreateBuilder(this); }
-    public override Builder CreateBuilderForType() { return new Builder(); }
-    public static Builder CreateBuilder(SimpleRequest prototype) {
-      return new Builder(prototype);
-    }
-
-    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
-    public sealed partial class Builder : pb::GeneratedBuilder<SimpleRequest, Builder> {
-      protected override Builder ThisBuilder {
-        get { return this; }
-      }
-      public Builder() {
-        result = DefaultInstance;
-        resultIsReadOnly = true;
-      }
-      internal Builder(SimpleRequest cloneFrom) {
-        result = cloneFrom;
-        resultIsReadOnly = true;
-      }
-
-      private bool resultIsReadOnly;
-      private SimpleRequest result;
-
-      private SimpleRequest PrepareBuilder() {
-        if (resultIsReadOnly) {
-          SimpleRequest original = result;
-          result = new SimpleRequest();
-          resultIsReadOnly = false;
-          MergeFrom(original);
-        }
-        return result;
-      }
-
-      public override bool IsInitialized {
-        get { return result.IsInitialized; }
-      }
-
-      protected override SimpleRequest MessageBeingBuilt {
-        get { return PrepareBuilder(); }
-      }
-
-      public override Builder Clear() {
-        result = DefaultInstance;
-        resultIsReadOnly = true;
-        return this;
-      }
-
-      public override Builder Clone() {
-        if (resultIsReadOnly) {
-          return new Builder(result);
-        } else {
-          return new Builder().MergeFrom(result);
-        }
-      }
-
-      public override pbd::MessageDescriptor DescriptorForType {
-        get { return global::grpc.testing.SimpleRequest.Descriptor; }
-      }
-
-      public override SimpleRequest DefaultInstanceForType {
-        get { return global::grpc.testing.SimpleRequest.DefaultInstance; }
-      }
-
-      public override SimpleRequest BuildPartial() {
-        if (resultIsReadOnly) {
-          return result;
-        }
-        resultIsReadOnly = true;
-        return result.MakeReadOnly();
-      }
-
-      public override Builder MergeFrom(pb::IMessage other) {
-        if (other is SimpleRequest) {
-          return MergeFrom((SimpleRequest) other);
-        } else {
-          base.MergeFrom(other);
-          return this;
-        }
-      }
-
-      public override Builder MergeFrom(SimpleRequest other) {
-        if (other == global::grpc.testing.SimpleRequest.DefaultInstance) return this;
-        PrepareBuilder();
-        if (other.HasResponseType) {
-          ResponseType = other.ResponseType;
-        }
-        if (other.HasResponseSize) {
-          ResponseSize = other.ResponseSize;
-        }
-        if (other.HasPayload) {
-          MergePayload(other.Payload);
-        }
-        if (other.HasFillUsername) {
-          FillUsername = other.FillUsername;
-        }
-        if (other.HasFillOauthScope) {
-          FillOauthScope = other.FillOauthScope;
-        }
-        this.MergeUnknownFields(other.UnknownFields);
-        return this;
-      }
-
-      public override Builder MergeFrom(pb::ICodedInputStream input) {
-        return MergeFrom(input, pb::ExtensionRegistry.Empty);
-      }
-
-      public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
-        PrepareBuilder();
-        pb::UnknownFieldSet.Builder unknownFields = null;
-        uint tag;
-        string field_name;
-        while (input.ReadTag(out tag, out field_name)) {
-          if(tag == 0 && field_name != null) {
-            int field_ordinal = global::System.Array.BinarySearch(_simpleRequestFieldNames, field_name, global::System.StringComparer.Ordinal);
-            if(field_ordinal >= 0)
-              tag = _simpleRequestFieldTags[field_ordinal];
-            else {
-              if (unknownFields == null) {
-                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
-              }
-              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);
-              continue;
-            }
+    public void MergeFrom(pb::CodedInputStream input) {
+      uint tag;
+      while ((tag = input.ReadTag()) != 0) {
+        switch(tag) {
+          default:
+            input.SkipLastField();
+            break;
+          case 8: {
+            responseType_ = (global::Grpc.Testing.PayloadType) input.ReadEnum();
+            break;
           }
-          switch (tag) {
-            case 0: {
-              throw pb::InvalidProtocolBufferException.InvalidTag();
+          case 16: {
+            ResponseSize = input.ReadInt32();
+            break;
+          }
+          case 26: {
+            if (payload_ == null) {
+              payload_ = new global::Grpc.Testing.Payload();
             }
-            default: {
-              if (pb::WireFormat.IsEndGroupTag(tag)) {
-                if (unknownFields != null) {
-                  this.UnknownFields = unknownFields.Build();
-                }
-                return this;
-              }
-              if (unknownFields == null) {
-                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
-              }
-              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);
-              break;
-            }
-            case 8: {
-              object unknown;
-              if(input.ReadEnum(ref result.responseType_, out unknown)) {
-                result.hasResponseType = true;
-              } else if(unknown is int) {
-                if (unknownFields == null) {
-                  unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
-                }
-                unknownFields.MergeVarintField(1, (ulong)(int)unknown);
-              }
-              break;
-            }
-            case 16: {
-              result.hasResponseSize = input.ReadInt32(ref result.responseSize_);
-              break;
-            }
-            case 26: {
-              global::grpc.testing.Payload.Builder subBuilder = global::grpc.testing.Payload.CreateBuilder();
-              if (result.hasPayload) {
-                subBuilder.MergeFrom(Payload);
-              }
-              input.ReadMessage(subBuilder, extensionRegistry);
-              Payload = subBuilder.BuildPartial();
-              break;
-            }
-            case 32: {
-              result.hasFillUsername = input.ReadBool(ref result.fillUsername_);
-              break;
-            }
-            case 40: {
-              result.hasFillOauthScope = input.ReadBool(ref result.fillOauthScope_);
-              break;
-            }
+            input.ReadMessage(payload_);
+            break;
+          }
+          case 32: {
+            FillUsername = input.ReadBool();
+            break;
+          }
+          case 40: {
+            FillOauthScope = input.ReadBool();
+            break;
           }
         }
-
-        if (unknownFields != null) {
-          this.UnknownFields = unknownFields.Build();
-        }
-        return this;
-      }
-
-
-      public bool HasResponseType {
-       get { return result.hasResponseType; }
-      }
-      public global::grpc.testing.PayloadType ResponseType {
-        get { return result.ResponseType; }
-        set { SetResponseType(value); }
-      }
-      public Builder SetResponseType(global::grpc.testing.PayloadType value) {
-        PrepareBuilder();
-        result.hasResponseType = true;
-        result.responseType_ = value;
-        return this;
-      }
-      public Builder ClearResponseType() {
-        PrepareBuilder();
-        result.hasResponseType = false;
-        result.responseType_ = global::grpc.testing.PayloadType.COMPRESSABLE;
-        return this;
-      }
-
-      public bool HasResponseSize {
-        get { return result.hasResponseSize; }
-      }
-      public int ResponseSize {
-        get { return result.ResponseSize; }
-        set { SetResponseSize(value); }
-      }
-      public Builder SetResponseSize(int value) {
-        PrepareBuilder();
-        result.hasResponseSize = true;
-        result.responseSize_ = value;
-        return this;
-      }
-      public Builder ClearResponseSize() {
-        PrepareBuilder();
-        result.hasResponseSize = false;
-        result.responseSize_ = 0;
-        return this;
-      }
-
-      public bool HasPayload {
-       get { return result.hasPayload; }
-      }
-      public global::grpc.testing.Payload Payload {
-        get { return result.Payload; }
-        set { SetPayload(value); }
-      }
-      public Builder SetPayload(global::grpc.testing.Payload value) {
-        pb::ThrowHelper.ThrowIfNull(value, "value");
-        PrepareBuilder();
-        result.hasPayload = true;
-        result.payload_ = value;
-        return this;
-      }
-      public Builder SetPayload(global::grpc.testing.Payload.Builder builderForValue) {
-        pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
-        PrepareBuilder();
-        result.hasPayload = true;
-        result.payload_ = builderForValue.Build();
-        return this;
-      }
-      public Builder MergePayload(global::grpc.testing.Payload value) {
-        pb::ThrowHelper.ThrowIfNull(value, "value");
-        PrepareBuilder();
-        if (result.hasPayload &&
-            result.payload_ != global::grpc.testing.Payload.DefaultInstance) {
-            result.payload_ = global::grpc.testing.Payload.CreateBuilder(result.payload_).MergeFrom(value).BuildPartial();
-        } else {
-          result.payload_ = value;
-        }
-        result.hasPayload = true;
-        return this;
-      }
-      public Builder ClearPayload() {
-        PrepareBuilder();
-        result.hasPayload = false;
-        result.payload_ = null;
-        return this;
-      }
-
-      public bool HasFillUsername {
-        get { return result.hasFillUsername; }
-      }
-      public bool FillUsername {
-        get { return result.FillUsername; }
-        set { SetFillUsername(value); }
-      }
-      public Builder SetFillUsername(bool value) {
-        PrepareBuilder();
-        result.hasFillUsername = true;
-        result.fillUsername_ = value;
-        return this;
-      }
-      public Builder ClearFillUsername() {
-        PrepareBuilder();
-        result.hasFillUsername = false;
-        result.fillUsername_ = false;
-        return this;
-      }
-
-      public bool HasFillOauthScope {
-        get { return result.hasFillOauthScope; }
-      }
-      public bool FillOauthScope {
-        get { return result.FillOauthScope; }
-        set { SetFillOauthScope(value); }
-      }
-      public Builder SetFillOauthScope(bool value) {
-        PrepareBuilder();
-        result.hasFillOauthScope = true;
-        result.fillOauthScope_ = value;
-        return this;
-      }
-      public Builder ClearFillOauthScope() {
-        PrepareBuilder();
-        result.hasFillOauthScope = false;
-        result.fillOauthScope_ = false;
-        return this;
       }
     }
-    static SimpleRequest() {
-      object.ReferenceEquals(global::grpc.testing.Messages.Descriptor, null);
-    }
+
   }
 
   [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
-  public sealed partial class SimpleResponse : pb::GeneratedMessage<SimpleResponse, SimpleResponse.Builder> {
-    private SimpleResponse() { }
-    private static readonly SimpleResponse defaultInstance = new SimpleResponse().MakeReadOnly();
-    private static readonly string[] _simpleResponseFieldNames = new string[] { "oauth_scope", "payload", "username" };
-    private static readonly uint[] _simpleResponseFieldTags = new uint[] { 26, 10, 18 };
-    public static SimpleResponse DefaultInstance {
-      get { return defaultInstance; }
+  public sealed partial class SimpleResponse : pb::IMessage<SimpleResponse> {
+    private static readonly pb::MessageParser<SimpleResponse> _parser = new pb::MessageParser<SimpleResponse>(() => new SimpleResponse());
+    public static pb::MessageParser<SimpleResponse> Parser { get { return _parser; } }
+
+    public static pbr::MessageDescriptor Descriptor {
+      get { return global::Grpc.Testing.Messages.Descriptor.MessageTypes[2]; }
     }
 
-    public override SimpleResponse DefaultInstanceForType {
-      get { return DefaultInstance; }
+    pbr::MessageDescriptor pb::IMessage.Descriptor {
+      get { return Descriptor; }
     }
 
-    protected override SimpleResponse ThisMessage {
-      get { return this; }
+    public SimpleResponse() {
+      OnConstruction();
     }
 
-    public static pbd::MessageDescriptor Descriptor {
-      get { return global::grpc.testing.Messages.internal__static_grpc_testing_SimpleResponse__Descriptor; }
+    partial void OnConstruction();
+
+    public SimpleResponse(SimpleResponse other) : this() {
+      Payload = other.payload_ != null ? other.Payload.Clone() : null;
+      username_ = other.username_;
+      oauthScope_ = other.oauthScope_;
     }
 
-    protected override pb::FieldAccess.FieldAccessorTable<SimpleResponse, SimpleResponse.Builder> InternalFieldAccessors {
-      get { return global::grpc.testing.Messages.internal__static_grpc_testing_SimpleResponse__FieldAccessorTable; }
+    public SimpleResponse Clone() {
+      return new SimpleResponse(this);
     }
 
     public const int PayloadFieldNumber = 1;
-    private bool hasPayload;
-    private global::grpc.testing.Payload payload_;
-    public bool HasPayload {
-      get { return hasPayload; }
-    }
-    public global::grpc.testing.Payload Payload {
-      get { return payload_ ?? global::grpc.testing.Payload.DefaultInstance; }
+    private global::Grpc.Testing.Payload payload_;
+    public global::Grpc.Testing.Payload Payload {
+      get { return payload_; }
+      set {
+        payload_ = value;
+      }
     }
 
     public const int UsernameFieldNumber = 2;
-    private bool hasUsername;
     private string username_ = "";
-    public bool HasUsername {
-      get { return hasUsername; }
-    }
     public string Username {
       get { return username_; }
+      set {
+        username_ = pb::Preconditions.CheckNotNull(value, "value");
+      }
     }
 
     public const int OauthScopeFieldNumber = 3;
-    private bool hasOauthScope;
     private string oauthScope_ = "";
-    public bool HasOauthScope {
-      get { return hasOauthScope; }
-    }
     public string OauthScope {
       get { return oauthScope_; }
+      set {
+        oauthScope_ = pb::Preconditions.CheckNotNull(value, "value");
+      }
     }
 
-    public override bool IsInitialized {
-      get {
+    public override bool Equals(object other) {
+      return Equals(other as SimpleResponse);
+    }
+
+    public bool Equals(SimpleResponse other) {
+      if (ReferenceEquals(other, null)) {
+        return false;
+      }
+      if (ReferenceEquals(other, this)) {
         return true;
       }
+      if (!object.Equals(Payload, other.Payload)) return false;
+      if (Username != other.Username) return false;
+      if (OauthScope != other.OauthScope) return false;
+      return true;
     }
 
-    public override void WriteTo(pb::ICodedOutputStream output) {
-      int size = SerializedSize;
-      string[] field_names = _simpleResponseFieldNames;
-      if (hasPayload) {
-        output.WriteMessage(1, field_names[1], Payload);
-      }
-      if (hasUsername) {
-        output.WriteString(2, field_names[2], Username);
-      }
-      if (hasOauthScope) {
-        output.WriteString(3, field_names[0], OauthScope);
-      }
-      UnknownFields.WriteTo(output);
+    public override int GetHashCode() {
+      int hash = 1;
+      if (payload_ != null) hash ^= Payload.GetHashCode();
+      if (Username.Length != 0) hash ^= Username.GetHashCode();
+      if (OauthScope.Length != 0) hash ^= OauthScope.GetHashCode();
+      return hash;
     }
 
-    private int memoizedSerializedSize = -1;
-    public override int SerializedSize {
-      get {
-        int size = memoizedSerializedSize;
-        if (size != -1) return size;
+    public override string ToString() {
+      return pb::JsonFormatter.Default.Format(this);
+    }
 
-        size = 0;
-        if (hasPayload) {
-          size += pb::CodedOutputStream.ComputeMessageSize(1, Payload);
+    public void WriteTo(pb::CodedOutputStream output) {
+      if (payload_ != null) {
+        output.WriteRawTag(10);
+        output.WriteMessage(Payload);
+      }
+      if (Username.Length != 0) {
+        output.WriteRawTag(18);
+        output.WriteString(Username);
+      }
+      if (OauthScope.Length != 0) {
+        output.WriteRawTag(26);
+        output.WriteString(OauthScope);
+      }
+    }
+
+    public int CalculateSize() {
+      int size = 0;
+      if (payload_ != null) {
+        size += 1 + pb::CodedOutputStream.ComputeMessageSize(Payload);
+      }
+      if (Username.Length != 0) {
+        size += 1 + pb::CodedOutputStream.ComputeStringSize(Username);
+      }
+      if (OauthScope.Length != 0) {
+        size += 1 + pb::CodedOutputStream.ComputeStringSize(OauthScope);
+      }
+      return size;
+    }
+
+    public void MergeFrom(SimpleResponse other) {
+      if (other == null) {
+        return;
+      }
+      if (other.payload_ != null) {
+        if (payload_ == null) {
+          payload_ = new global::Grpc.Testing.Payload();
         }
-        if (hasUsername) {
-          size += pb::CodedOutputStream.ComputeStringSize(2, Username);
-        }
-        if (hasOauthScope) {
-          size += pb::CodedOutputStream.ComputeStringSize(3, OauthScope);
-        }
-        size += UnknownFields.SerializedSize;
-        memoizedSerializedSize = size;
-        return size;
+        Payload.MergeFrom(other.Payload);
+      }
+      if (other.Username.Length != 0) {
+        Username = other.Username;
+      }
+      if (other.OauthScope.Length != 0) {
+        OauthScope = other.OauthScope;
       }
     }
 
-    public static SimpleResponse ParseFrom(pb::ByteString data) {
-      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
-    }
-    public static SimpleResponse ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
-      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
-    }
-    public static SimpleResponse ParseFrom(byte[] data) {
-      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
-    }
-    public static SimpleResponse ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
-      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
-    }
-    public static SimpleResponse ParseFrom(global::System.IO.Stream input) {
-      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
-    }
-    public static SimpleResponse ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
-      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
-    }
-    public static SimpleResponse ParseDelimitedFrom(global::System.IO.Stream input) {
-      return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
-    }
-    public static SimpleResponse ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
-      return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
-    }
-    public static SimpleResponse ParseFrom(pb::ICodedInputStream input) {
-      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
-    }
-    public static SimpleResponse ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
-      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
-    }
-    private SimpleResponse MakeReadOnly() {
-      return this;
-    }
-
-    public static Builder CreateBuilder() { return new Builder(); }
-    public override Builder ToBuilder() { return CreateBuilder(this); }
-    public override Builder CreateBuilderForType() { return new Builder(); }
-    public static Builder CreateBuilder(SimpleResponse prototype) {
-      return new Builder(prototype);
-    }
-
-    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
-    public sealed partial class Builder : pb::GeneratedBuilder<SimpleResponse, Builder> {
-      protected override Builder ThisBuilder {
-        get { return this; }
-      }
-      public Builder() {
-        result = DefaultInstance;
-        resultIsReadOnly = true;
-      }
-      internal Builder(SimpleResponse cloneFrom) {
-        result = cloneFrom;
-        resultIsReadOnly = true;
-      }
-
-      private bool resultIsReadOnly;
-      private SimpleResponse result;
-
-      private SimpleResponse PrepareBuilder() {
-        if (resultIsReadOnly) {
-          SimpleResponse original = result;
-          result = new SimpleResponse();
-          resultIsReadOnly = false;
-          MergeFrom(original);
-        }
-        return result;
-      }
-
-      public override bool IsInitialized {
-        get { return result.IsInitialized; }
-      }
-
-      protected override SimpleResponse MessageBeingBuilt {
-        get { return PrepareBuilder(); }
-      }
-
-      public override Builder Clear() {
-        result = DefaultInstance;
-        resultIsReadOnly = true;
-        return this;
-      }
-
-      public override Builder Clone() {
-        if (resultIsReadOnly) {
-          return new Builder(result);
-        } else {
-          return new Builder().MergeFrom(result);
-        }
-      }
-
-      public override pbd::MessageDescriptor DescriptorForType {
-        get { return global::grpc.testing.SimpleResponse.Descriptor; }
-      }
-
-      public override SimpleResponse DefaultInstanceForType {
-        get { return global::grpc.testing.SimpleResponse.DefaultInstance; }
-      }
-
-      public override SimpleResponse BuildPartial() {
-        if (resultIsReadOnly) {
-          return result;
-        }
-        resultIsReadOnly = true;
-        return result.MakeReadOnly();
-      }
-
-      public override Builder MergeFrom(pb::IMessage other) {
-        if (other is SimpleResponse) {
-          return MergeFrom((SimpleResponse) other);
-        } else {
-          base.MergeFrom(other);
-          return this;
-        }
-      }
-
-      public override Builder MergeFrom(SimpleResponse other) {
-        if (other == global::grpc.testing.SimpleResponse.DefaultInstance) return this;
-        PrepareBuilder();
-        if (other.HasPayload) {
-          MergePayload(other.Payload);
-        }
-        if (other.HasUsername) {
-          Username = other.Username;
-        }
-        if (other.HasOauthScope) {
-          OauthScope = other.OauthScope;
-        }
-        this.MergeUnknownFields(other.UnknownFields);
-        return this;
-      }
-
-      public override Builder MergeFrom(pb::ICodedInputStream input) {
-        return MergeFrom(input, pb::ExtensionRegistry.Empty);
-      }
-
-      public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
-        PrepareBuilder();
-        pb::UnknownFieldSet.Builder unknownFields = null;
-        uint tag;
-        string field_name;
-        while (input.ReadTag(out tag, out field_name)) {
-          if(tag == 0 && field_name != null) {
-            int field_ordinal = global::System.Array.BinarySearch(_simpleResponseFieldNames, field_name, global::System.StringComparer.Ordinal);
-            if(field_ordinal >= 0)
-              tag = _simpleResponseFieldTags[field_ordinal];
-            else {
-              if (unknownFields == null) {
-                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
-              }
-              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);
-              continue;
+    public void MergeFrom(pb::CodedInputStream input) {
+      uint tag;
+      while ((tag = input.ReadTag()) != 0) {
+        switch(tag) {
+          default:
+            input.SkipLastField();
+            break;
+          case 10: {
+            if (payload_ == null) {
+              payload_ = new global::Grpc.Testing.Payload();
             }
+            input.ReadMessage(payload_);
+            break;
           }
-          switch (tag) {
-            case 0: {
-              throw pb::InvalidProtocolBufferException.InvalidTag();
-            }
-            default: {
-              if (pb::WireFormat.IsEndGroupTag(tag)) {
-                if (unknownFields != null) {
-                  this.UnknownFields = unknownFields.Build();
-                }
-                return this;
-              }
-              if (unknownFields == null) {
-                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
-              }
-              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);
-              break;
-            }
-            case 10: {
-              global::grpc.testing.Payload.Builder subBuilder = global::grpc.testing.Payload.CreateBuilder();
-              if (result.hasPayload) {
-                subBuilder.MergeFrom(Payload);
-              }
-              input.ReadMessage(subBuilder, extensionRegistry);
-              Payload = subBuilder.BuildPartial();
-              break;
-            }
-            case 18: {
-              result.hasUsername = input.ReadString(ref result.username_);
-              break;
-            }
-            case 26: {
-              result.hasOauthScope = input.ReadString(ref result.oauthScope_);
-              break;
-            }
+          case 18: {
+            Username = input.ReadString();
+            break;
+          }
+          case 26: {
+            OauthScope = input.ReadString();
+            break;
           }
         }
-
-        if (unknownFields != null) {
-          this.UnknownFields = unknownFields.Build();
-        }
-        return this;
-      }
-
-
-      public bool HasPayload {
-       get { return result.hasPayload; }
-      }
-      public global::grpc.testing.Payload Payload {
-        get { return result.Payload; }
-        set { SetPayload(value); }
-      }
-      public Builder SetPayload(global::grpc.testing.Payload value) {
-        pb::ThrowHelper.ThrowIfNull(value, "value");
-        PrepareBuilder();
-        result.hasPayload = true;
-        result.payload_ = value;
-        return this;
-      }
-      public Builder SetPayload(global::grpc.testing.Payload.Builder builderForValue) {
-        pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
-        PrepareBuilder();
-        result.hasPayload = true;
-        result.payload_ = builderForValue.Build();
-        return this;
-      }
-      public Builder MergePayload(global::grpc.testing.Payload value) {
-        pb::ThrowHelper.ThrowIfNull(value, "value");
-        PrepareBuilder();
-        if (result.hasPayload &&
-            result.payload_ != global::grpc.testing.Payload.DefaultInstance) {
-            result.payload_ = global::grpc.testing.Payload.CreateBuilder(result.payload_).MergeFrom(value).BuildPartial();
-        } else {
-          result.payload_ = value;
-        }
-        result.hasPayload = true;
-        return this;
-      }
-      public Builder ClearPayload() {
-        PrepareBuilder();
-        result.hasPayload = false;
-        result.payload_ = null;
-        return this;
-      }
-
-      public bool HasUsername {
-        get { return result.hasUsername; }
-      }
-      public string Username {
-        get { return result.Username; }
-        set { SetUsername(value); }
-      }
-      public Builder SetUsername(string value) {
-        pb::ThrowHelper.ThrowIfNull(value, "value");
-        PrepareBuilder();
-        result.hasUsername = true;
-        result.username_ = value;
-        return this;
-      }
-      public Builder ClearUsername() {
-        PrepareBuilder();
-        result.hasUsername = false;
-        result.username_ = "";
-        return this;
-      }
-
-      public bool HasOauthScope {
-        get { return result.hasOauthScope; }
-      }
-      public string OauthScope {
-        get { return result.OauthScope; }
-        set { SetOauthScope(value); }
-      }
-      public Builder SetOauthScope(string value) {
-        pb::ThrowHelper.ThrowIfNull(value, "value");
-        PrepareBuilder();
-        result.hasOauthScope = true;
-        result.oauthScope_ = value;
-        return this;
-      }
-      public Builder ClearOauthScope() {
-        PrepareBuilder();
-        result.hasOauthScope = false;
-        result.oauthScope_ = "";
-        return this;
       }
     }
-    static SimpleResponse() {
-      object.ReferenceEquals(global::grpc.testing.Messages.Descriptor, null);
-    }
+
   }
 
   [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
-  public sealed partial class StreamingInputCallRequest : pb::GeneratedMessage<StreamingInputCallRequest, StreamingInputCallRequest.Builder> {
-    private StreamingInputCallRequest() { }
-    private static readonly StreamingInputCallRequest defaultInstance = new StreamingInputCallRequest().MakeReadOnly();
-    private static readonly string[] _streamingInputCallRequestFieldNames = new string[] { "payload" };
-    private static readonly uint[] _streamingInputCallRequestFieldTags = new uint[] { 10 };
-    public static StreamingInputCallRequest DefaultInstance {
-      get { return defaultInstance; }
+  public sealed partial class StreamingInputCallRequest : pb::IMessage<StreamingInputCallRequest> {
+    private static readonly pb::MessageParser<StreamingInputCallRequest> _parser = new pb::MessageParser<StreamingInputCallRequest>(() => new StreamingInputCallRequest());
+    public static pb::MessageParser<StreamingInputCallRequest> Parser { get { return _parser; } }
+
+    public static pbr::MessageDescriptor Descriptor {
+      get { return global::Grpc.Testing.Messages.Descriptor.MessageTypes[3]; }
     }
 
-    public override StreamingInputCallRequest DefaultInstanceForType {
-      get { return DefaultInstance; }
+    pbr::MessageDescriptor pb::IMessage.Descriptor {
+      get { return Descriptor; }
     }
 
-    protected override StreamingInputCallRequest ThisMessage {
-      get { return this; }
+    public StreamingInputCallRequest() {
+      OnConstruction();
     }
 
-    public static pbd::MessageDescriptor Descriptor {
-      get { return global::grpc.testing.Messages.internal__static_grpc_testing_StreamingInputCallRequest__Descriptor; }
+    partial void OnConstruction();
+
+    public StreamingInputCallRequest(StreamingInputCallRequest other) : this() {
+      Payload = other.payload_ != null ? other.Payload.Clone() : null;
     }
 
-    protected override pb::FieldAccess.FieldAccessorTable<StreamingInputCallRequest, StreamingInputCallRequest.Builder> InternalFieldAccessors {
-      get { return global::grpc.testing.Messages.internal__static_grpc_testing_StreamingInputCallRequest__FieldAccessorTable; }
+    public StreamingInputCallRequest Clone() {
+      return new StreamingInputCallRequest(this);
     }
 
     public const int PayloadFieldNumber = 1;
-    private bool hasPayload;
-    private global::grpc.testing.Payload payload_;
-    public bool HasPayload {
-      get { return hasPayload; }
-    }
-    public global::grpc.testing.Payload Payload {
-      get { return payload_ ?? global::grpc.testing.Payload.DefaultInstance; }
+    private global::Grpc.Testing.Payload payload_;
+    public global::Grpc.Testing.Payload Payload {
+      get { return payload_; }
+      set {
+        payload_ = value;
+      }
     }
 
-    public override bool IsInitialized {
-      get {
+    public override bool Equals(object other) {
+      return Equals(other as StreamingInputCallRequest);
+    }
+
+    public bool Equals(StreamingInputCallRequest other) {
+      if (ReferenceEquals(other, null)) {
+        return false;
+      }
+      if (ReferenceEquals(other, this)) {
         return true;
       }
+      if (!object.Equals(Payload, other.Payload)) return false;
+      return true;
     }
 
-    public override void WriteTo(pb::ICodedOutputStream output) {
-      int size = SerializedSize;
-      string[] field_names = _streamingInputCallRequestFieldNames;
-      if (hasPayload) {
-        output.WriteMessage(1, field_names[0], Payload);
+    public override int GetHashCode() {
+      int hash = 1;
+      if (payload_ != null) hash ^= Payload.GetHashCode();
+      return hash;
+    }
+
+    public override string ToString() {
+      return pb::JsonFormatter.Default.Format(this);
+    }
+
+    public void WriteTo(pb::CodedOutputStream output) {
+      if (payload_ != null) {
+        output.WriteRawTag(10);
+        output.WriteMessage(Payload);
       }
-      UnknownFields.WriteTo(output);
     }
 
-    private int memoizedSerializedSize = -1;
-    public override int SerializedSize {
-      get {
-        int size = memoizedSerializedSize;
-        if (size != -1) return size;
+    public int CalculateSize() {
+      int size = 0;
+      if (payload_ != null) {
+        size += 1 + pb::CodedOutputStream.ComputeMessageSize(Payload);
+      }
+      return size;
+    }
 
-        size = 0;
-        if (hasPayload) {
-          size += pb::CodedOutputStream.ComputeMessageSize(1, Payload);
+    public void MergeFrom(StreamingInputCallRequest other) {
+      if (other == null) {
+        return;
+      }
+      if (other.payload_ != null) {
+        if (payload_ == null) {
+          payload_ = new global::Grpc.Testing.Payload();
         }
-        size += UnknownFields.SerializedSize;
-        memoizedSerializedSize = size;
-        return size;
+        Payload.MergeFrom(other.Payload);
       }
     }
 
-    public static StreamingInputCallRequest ParseFrom(pb::ByteString data) {
-      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
-    }
-    public static StreamingInputCallRequest ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
-      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
-    }
-    public static StreamingInputCallRequest ParseFrom(byte[] data) {
-      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
-    }
-    public static StreamingInputCallRequest ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
-      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
-    }
-    public static StreamingInputCallRequest ParseFrom(global::System.IO.Stream input) {
-      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
-    }
-    public static StreamingInputCallRequest ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
-      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
-    }
-    public static StreamingInputCallRequest ParseDelimitedFrom(global::System.IO.Stream input) {
-      return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
-    }
-    public static StreamingInputCallRequest ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
-      return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
-    }
-    public static StreamingInputCallRequest ParseFrom(pb::ICodedInputStream input) {
-      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
-    }
-    public static StreamingInputCallRequest ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
-      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
-    }
-    private StreamingInputCallRequest MakeReadOnly() {
-      return this;
-    }
-
-    public static Builder CreateBuilder() { return new Builder(); }
-    public override Builder ToBuilder() { return CreateBuilder(this); }
-    public override Builder CreateBuilderForType() { return new Builder(); }
-    public static Builder CreateBuilder(StreamingInputCallRequest prototype) {
-      return new Builder(prototype);
-    }
-
-    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
-    public sealed partial class Builder : pb::GeneratedBuilder<StreamingInputCallRequest, Builder> {
-      protected override Builder ThisBuilder {
-        get { return this; }
-      }
-      public Builder() {
-        result = DefaultInstance;
-        resultIsReadOnly = true;
-      }
-      internal Builder(StreamingInputCallRequest cloneFrom) {
-        result = cloneFrom;
-        resultIsReadOnly = true;
-      }
-
-      private bool resultIsReadOnly;
-      private StreamingInputCallRequest result;
-
-      private StreamingInputCallRequest PrepareBuilder() {
-        if (resultIsReadOnly) {
-          StreamingInputCallRequest original = result;
-          result = new StreamingInputCallRequest();
-          resultIsReadOnly = false;
-          MergeFrom(original);
-        }
-        return result;
-      }
-
-      public override bool IsInitialized {
-        get { return result.IsInitialized; }
-      }
-
-      protected override StreamingInputCallRequest MessageBeingBuilt {
-        get { return PrepareBuilder(); }
-      }
-
-      public override Builder Clear() {
-        result = DefaultInstance;
-        resultIsReadOnly = true;
-        return this;
-      }
-
-      public override Builder Clone() {
-        if (resultIsReadOnly) {
-          return new Builder(result);
-        } else {
-          return new Builder().MergeFrom(result);
-        }
-      }
-
-      public override pbd::MessageDescriptor DescriptorForType {
-        get { return global::grpc.testing.StreamingInputCallRequest.Descriptor; }
-      }
-
-      public override StreamingInputCallRequest DefaultInstanceForType {
-        get { return global::grpc.testing.StreamingInputCallRequest.DefaultInstance; }
-      }
-
-      public override StreamingInputCallRequest BuildPartial() {
-        if (resultIsReadOnly) {
-          return result;
-        }
-        resultIsReadOnly = true;
-        return result.MakeReadOnly();
-      }
-
-      public override Builder MergeFrom(pb::IMessage other) {
-        if (other is StreamingInputCallRequest) {
-          return MergeFrom((StreamingInputCallRequest) other);
-        } else {
-          base.MergeFrom(other);
-          return this;
-        }
-      }
-
-      public override Builder MergeFrom(StreamingInputCallRequest other) {
-        if (other == global::grpc.testing.StreamingInputCallRequest.DefaultInstance) return this;
-        PrepareBuilder();
-        if (other.HasPayload) {
-          MergePayload(other.Payload);
-        }
-        this.MergeUnknownFields(other.UnknownFields);
-        return this;
-      }
-
-      public override Builder MergeFrom(pb::ICodedInputStream input) {
-        return MergeFrom(input, pb::ExtensionRegistry.Empty);
-      }
-
-      public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
-        PrepareBuilder();
-        pb::UnknownFieldSet.Builder unknownFields = null;
-        uint tag;
-        string field_name;
-        while (input.ReadTag(out tag, out field_name)) {
-          if(tag == 0 && field_name != null) {
-            int field_ordinal = global::System.Array.BinarySearch(_streamingInputCallRequestFieldNames, field_name, global::System.StringComparer.Ordinal);
-            if(field_ordinal >= 0)
-              tag = _streamingInputCallRequestFieldTags[field_ordinal];
-            else {
-              if (unknownFields == null) {
-                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
-              }
-              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);
-              continue;
+    public void MergeFrom(pb::CodedInputStream input) {
+      uint tag;
+      while ((tag = input.ReadTag()) != 0) {
+        switch(tag) {
+          default:
+            input.SkipLastField();
+            break;
+          case 10: {
+            if (payload_ == null) {
+              payload_ = new global::Grpc.Testing.Payload();
             }
-          }
-          switch (tag) {
-            case 0: {
-              throw pb::InvalidProtocolBufferException.InvalidTag();
-            }
-            default: {
-              if (pb::WireFormat.IsEndGroupTag(tag)) {
-                if (unknownFields != null) {
-                  this.UnknownFields = unknownFields.Build();
-                }
-                return this;
-              }
-              if (unknownFields == null) {
-                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
-              }
-              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);
-              break;
-            }
-            case 10: {
-              global::grpc.testing.Payload.Builder subBuilder = global::grpc.testing.Payload.CreateBuilder();
-              if (result.hasPayload) {
-                subBuilder.MergeFrom(Payload);
-              }
-              input.ReadMessage(subBuilder, extensionRegistry);
-              Payload = subBuilder.BuildPartial();
-              break;
-            }
+            input.ReadMessage(payload_);
+            break;
           }
         }
-
-        if (unknownFields != null) {
-          this.UnknownFields = unknownFields.Build();
-        }
-        return this;
-      }
-
-
-      public bool HasPayload {
-       get { return result.hasPayload; }
-      }
-      public global::grpc.testing.Payload Payload {
-        get { return result.Payload; }
-        set { SetPayload(value); }
-      }
-      public Builder SetPayload(global::grpc.testing.Payload value) {
-        pb::ThrowHelper.ThrowIfNull(value, "value");
-        PrepareBuilder();
-        result.hasPayload = true;
-        result.payload_ = value;
-        return this;
-      }
-      public Builder SetPayload(global::grpc.testing.Payload.Builder builderForValue) {
-        pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
-        PrepareBuilder();
-        result.hasPayload = true;
-        result.payload_ = builderForValue.Build();
-        return this;
-      }
-      public Builder MergePayload(global::grpc.testing.Payload value) {
-        pb::ThrowHelper.ThrowIfNull(value, "value");
-        PrepareBuilder();
-        if (result.hasPayload &&
-            result.payload_ != global::grpc.testing.Payload.DefaultInstance) {
-            result.payload_ = global::grpc.testing.Payload.CreateBuilder(result.payload_).MergeFrom(value).BuildPartial();
-        } else {
-          result.payload_ = value;
-        }
-        result.hasPayload = true;
-        return this;
-      }
-      public Builder ClearPayload() {
-        PrepareBuilder();
-        result.hasPayload = false;
-        result.payload_ = null;
-        return this;
       }
     }
-    static StreamingInputCallRequest() {
-      object.ReferenceEquals(global::grpc.testing.Messages.Descriptor, null);
-    }
+
   }
 
   [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
-  public sealed partial class StreamingInputCallResponse : pb::GeneratedMessage<StreamingInputCallResponse, StreamingInputCallResponse.Builder> {
-    private StreamingInputCallResponse() { }
-    private static readonly StreamingInputCallResponse defaultInstance = new StreamingInputCallResponse().MakeReadOnly();
-    private static readonly string[] _streamingInputCallResponseFieldNames = new string[] { "aggregated_payload_size" };
-    private static readonly uint[] _streamingInputCallResponseFieldTags = new uint[] { 8 };
-    public static StreamingInputCallResponse DefaultInstance {
-      get { return defaultInstance; }
+  public sealed partial class StreamingInputCallResponse : pb::IMessage<StreamingInputCallResponse> {
+    private static readonly pb::MessageParser<StreamingInputCallResponse> _parser = new pb::MessageParser<StreamingInputCallResponse>(() => new StreamingInputCallResponse());
+    public static pb::MessageParser<StreamingInputCallResponse> Parser { get { return _parser; } }
+
+    public static pbr::MessageDescriptor Descriptor {
+      get { return global::Grpc.Testing.Messages.Descriptor.MessageTypes[4]; }
     }
 
-    public override StreamingInputCallResponse DefaultInstanceForType {
-      get { return DefaultInstance; }
+    pbr::MessageDescriptor pb::IMessage.Descriptor {
+      get { return Descriptor; }
     }
 
-    protected override StreamingInputCallResponse ThisMessage {
-      get { return this; }
+    public StreamingInputCallResponse() {
+      OnConstruction();
     }
 
-    public static pbd::MessageDescriptor Descriptor {
-      get { return global::grpc.testing.Messages.internal__static_grpc_testing_StreamingInputCallResponse__Descriptor; }
+    partial void OnConstruction();
+
+    public StreamingInputCallResponse(StreamingInputCallResponse other) : this() {
+      aggregatedPayloadSize_ = other.aggregatedPayloadSize_;
     }
 
-    protected override pb::FieldAccess.FieldAccessorTable<StreamingInputCallResponse, StreamingInputCallResponse.Builder> InternalFieldAccessors {
-      get { return global::grpc.testing.Messages.internal__static_grpc_testing_StreamingInputCallResponse__FieldAccessorTable; }
+    public StreamingInputCallResponse Clone() {
+      return new StreamingInputCallResponse(this);
     }
 
     public const int AggregatedPayloadSizeFieldNumber = 1;
-    private bool hasAggregatedPayloadSize;
     private int aggregatedPayloadSize_;
-    public bool HasAggregatedPayloadSize {
-      get { return hasAggregatedPayloadSize; }
-    }
     public int AggregatedPayloadSize {
       get { return aggregatedPayloadSize_; }
+      set {
+        aggregatedPayloadSize_ = value;
+      }
     }
 
-    public override bool IsInitialized {
-      get {
+    public override bool Equals(object other) {
+      return Equals(other as StreamingInputCallResponse);
+    }
+
+    public bool Equals(StreamingInputCallResponse other) {
+      if (ReferenceEquals(other, null)) {
+        return false;
+      }
+      if (ReferenceEquals(other, this)) {
         return true;
       }
+      if (AggregatedPayloadSize != other.AggregatedPayloadSize) return false;
+      return true;
     }
 
-    public override void WriteTo(pb::ICodedOutputStream output) {
-      int size = SerializedSize;
-      string[] field_names = _streamingInputCallResponseFieldNames;
-      if (hasAggregatedPayloadSize) {
-        output.WriteInt32(1, field_names[0], AggregatedPayloadSize);
-      }
-      UnknownFields.WriteTo(output);
+    public override int GetHashCode() {
+      int hash = 1;
+      if (AggregatedPayloadSize != 0) hash ^= AggregatedPayloadSize.GetHashCode();
+      return hash;
     }
 
-    private int memoizedSerializedSize = -1;
-    public override int SerializedSize {
-      get {
-        int size = memoizedSerializedSize;
-        if (size != -1) return size;
+    public override string ToString() {
+      return pb::JsonFormatter.Default.Format(this);
+    }
 
-        size = 0;
-        if (hasAggregatedPayloadSize) {
-          size += pb::CodedOutputStream.ComputeInt32Size(1, AggregatedPayloadSize);
-        }
-        size += UnknownFields.SerializedSize;
-        memoizedSerializedSize = size;
-        return size;
+    public void WriteTo(pb::CodedOutputStream output) {
+      if (AggregatedPayloadSize != 0) {
+        output.WriteRawTag(8);
+        output.WriteInt32(AggregatedPayloadSize);
       }
     }
 
-    public static StreamingInputCallResponse ParseFrom(pb::ByteString data) {
-      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
-    }
-    public static StreamingInputCallResponse ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
-      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
-    }
-    public static StreamingInputCallResponse ParseFrom(byte[] data) {
-      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
-    }
-    public static StreamingInputCallResponse ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
-      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
-    }
-    public static StreamingInputCallResponse ParseFrom(global::System.IO.Stream input) {
-      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
-    }
-    public static StreamingInputCallResponse ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
-      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
-    }
-    public static StreamingInputCallResponse ParseDelimitedFrom(global::System.IO.Stream input) {
-      return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
-    }
-    public static StreamingInputCallResponse ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
-      return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
-    }
-    public static StreamingInputCallResponse ParseFrom(pb::ICodedInputStream input) {
-      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
-    }
-    public static StreamingInputCallResponse ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
-      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
-    }
-    private StreamingInputCallResponse MakeReadOnly() {
-      return this;
+    public int CalculateSize() {
+      int size = 0;
+      if (AggregatedPayloadSize != 0) {
+        size += 1 + pb::CodedOutputStream.ComputeInt32Size(AggregatedPayloadSize);
+      }
+      return size;
     }
 
-    public static Builder CreateBuilder() { return new Builder(); }
-    public override Builder ToBuilder() { return CreateBuilder(this); }
-    public override Builder CreateBuilderForType() { return new Builder(); }
-    public static Builder CreateBuilder(StreamingInputCallResponse prototype) {
-      return new Builder(prototype);
+    public void MergeFrom(StreamingInputCallResponse other) {
+      if (other == null) {
+        return;
+      }
+      if (other.AggregatedPayloadSize != 0) {
+        AggregatedPayloadSize = other.AggregatedPayloadSize;
+      }
     }
 
-    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
-    public sealed partial class Builder : pb::GeneratedBuilder<StreamingInputCallResponse, Builder> {
-      protected override Builder ThisBuilder {
-        get { return this; }
-      }
-      public Builder() {
-        result = DefaultInstance;
-        resultIsReadOnly = true;
-      }
-      internal Builder(StreamingInputCallResponse cloneFrom) {
-        result = cloneFrom;
-        resultIsReadOnly = true;
-      }
-
-      private bool resultIsReadOnly;
-      private StreamingInputCallResponse result;
-
-      private StreamingInputCallResponse PrepareBuilder() {
-        if (resultIsReadOnly) {
-          StreamingInputCallResponse original = result;
-          result = new StreamingInputCallResponse();
-          resultIsReadOnly = false;
-          MergeFrom(original);
-        }
-        return result;
-      }
-
-      public override bool IsInitialized {
-        get { return result.IsInitialized; }
-      }
-
-      protected override StreamingInputCallResponse MessageBeingBuilt {
-        get { return PrepareBuilder(); }
-      }
-
-      public override Builder Clear() {
-        result = DefaultInstance;
-        resultIsReadOnly = true;
-        return this;
-      }
-
-      public override Builder Clone() {
-        if (resultIsReadOnly) {
-          return new Builder(result);
-        } else {
-          return new Builder().MergeFrom(result);
-        }
-      }
-
-      public override pbd::MessageDescriptor DescriptorForType {
-        get { return global::grpc.testing.StreamingInputCallResponse.Descriptor; }
-      }
-
-      public override StreamingInputCallResponse DefaultInstanceForType {
-        get { return global::grpc.testing.StreamingInputCallResponse.DefaultInstance; }
-      }
-
-      public override StreamingInputCallResponse BuildPartial() {
-        if (resultIsReadOnly) {
-          return result;
-        }
-        resultIsReadOnly = true;
-        return result.MakeReadOnly();
-      }
-
-      public override Builder MergeFrom(pb::IMessage other) {
-        if (other is StreamingInputCallResponse) {
-          return MergeFrom((StreamingInputCallResponse) other);
-        } else {
-          base.MergeFrom(other);
-          return this;
-        }
-      }
-
-      public override Builder MergeFrom(StreamingInputCallResponse other) {
-        if (other == global::grpc.testing.StreamingInputCallResponse.DefaultInstance) return this;
-        PrepareBuilder();
-        if (other.HasAggregatedPayloadSize) {
-          AggregatedPayloadSize = other.AggregatedPayloadSize;
-        }
-        this.MergeUnknownFields(other.UnknownFields);
-        return this;
-      }
-
-      public override Builder MergeFrom(pb::ICodedInputStream input) {
-        return MergeFrom(input, pb::ExtensionRegistry.Empty);
-      }
-
-      public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
-        PrepareBuilder();
-        pb::UnknownFieldSet.Builder unknownFields = null;
-        uint tag;
-        string field_name;
-        while (input.ReadTag(out tag, out field_name)) {
-          if(tag == 0 && field_name != null) {
-            int field_ordinal = global::System.Array.BinarySearch(_streamingInputCallResponseFieldNames, field_name, global::System.StringComparer.Ordinal);
-            if(field_ordinal >= 0)
-              tag = _streamingInputCallResponseFieldTags[field_ordinal];
-            else {
-              if (unknownFields == null) {
-                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
-              }
-              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);
-              continue;
-            }
-          }
-          switch (tag) {
-            case 0: {
-              throw pb::InvalidProtocolBufferException.InvalidTag();
-            }
-            default: {
-              if (pb::WireFormat.IsEndGroupTag(tag)) {
-                if (unknownFields != null) {
-                  this.UnknownFields = unknownFields.Build();
-                }
-                return this;
-              }
-              if (unknownFields == null) {
-                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
-              }
-              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);
-              break;
-            }
-            case 8: {
-              result.hasAggregatedPayloadSize = input.ReadInt32(ref result.aggregatedPayloadSize_);
-              break;
-            }
+    public void MergeFrom(pb::CodedInputStream input) {
+      uint tag;
+      while ((tag = input.ReadTag()) != 0) {
+        switch(tag) {
+          default:
+            input.SkipLastField();
+            break;
+          case 8: {
+            AggregatedPayloadSize = input.ReadInt32();
+            break;
           }
         }
-
-        if (unknownFields != null) {
-          this.UnknownFields = unknownFields.Build();
-        }
-        return this;
-      }
-
-
-      public bool HasAggregatedPayloadSize {
-        get { return result.hasAggregatedPayloadSize; }
-      }
-      public int AggregatedPayloadSize {
-        get { return result.AggregatedPayloadSize; }
-        set { SetAggregatedPayloadSize(value); }
-      }
-      public Builder SetAggregatedPayloadSize(int value) {
-        PrepareBuilder();
-        result.hasAggregatedPayloadSize = true;
-        result.aggregatedPayloadSize_ = value;
-        return this;
-      }
-      public Builder ClearAggregatedPayloadSize() {
-        PrepareBuilder();
-        result.hasAggregatedPayloadSize = false;
-        result.aggregatedPayloadSize_ = 0;
-        return this;
       }
     }
-    static StreamingInputCallResponse() {
-      object.ReferenceEquals(global::grpc.testing.Messages.Descriptor, null);
-    }
+
   }
 
   [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
-  public sealed partial class ResponseParameters : pb::GeneratedMessage<ResponseParameters, ResponseParameters.Builder> {
-    private ResponseParameters() { }
-    private static readonly ResponseParameters defaultInstance = new ResponseParameters().MakeReadOnly();
-    private static readonly string[] _responseParametersFieldNames = new string[] { "interval_us", "size" };
-    private static readonly uint[] _responseParametersFieldTags = new uint[] { 16, 8 };
-    public static ResponseParameters DefaultInstance {
-      get { return defaultInstance; }
+  public sealed partial class ResponseParameters : pb::IMessage<ResponseParameters> {
+    private static readonly pb::MessageParser<ResponseParameters> _parser = new pb::MessageParser<ResponseParameters>(() => new ResponseParameters());
+    public static pb::MessageParser<ResponseParameters> Parser { get { return _parser; } }
+
+    public static pbr::MessageDescriptor Descriptor {
+      get { return global::Grpc.Testing.Messages.Descriptor.MessageTypes[5]; }
     }
 
-    public override ResponseParameters DefaultInstanceForType {
-      get { return DefaultInstance; }
+    pbr::MessageDescriptor pb::IMessage.Descriptor {
+      get { return Descriptor; }
     }
 
-    protected override ResponseParameters ThisMessage {
-      get { return this; }
+    public ResponseParameters() {
+      OnConstruction();
     }
 
-    public static pbd::MessageDescriptor Descriptor {
-      get { return global::grpc.testing.Messages.internal__static_grpc_testing_ResponseParameters__Descriptor; }
+    partial void OnConstruction();
+
+    public ResponseParameters(ResponseParameters other) : this() {
+      size_ = other.size_;
+      intervalUs_ = other.intervalUs_;
     }
 
-    protected override pb::FieldAccess.FieldAccessorTable<ResponseParameters, ResponseParameters.Builder> InternalFieldAccessors {
-      get { return global::grpc.testing.Messages.internal__static_grpc_testing_ResponseParameters__FieldAccessorTable; }
+    public ResponseParameters Clone() {
+      return new ResponseParameters(this);
     }
 
     public const int SizeFieldNumber = 1;
-    private bool hasSize;
     private int size_;
-    public bool HasSize {
-      get { return hasSize; }
-    }
     public int Size {
       get { return size_; }
+      set {
+        size_ = value;
+      }
     }
 
     public const int IntervalUsFieldNumber = 2;
-    private bool hasIntervalUs;
     private int intervalUs_;
-    public bool HasIntervalUs {
-      get { return hasIntervalUs; }
-    }
     public int IntervalUs {
       get { return intervalUs_; }
+      set {
+        intervalUs_ = value;
+      }
     }
 
-    public override bool IsInitialized {
-      get {
+    public override bool Equals(object other) {
+      return Equals(other as ResponseParameters);
+    }
+
+    public bool Equals(ResponseParameters other) {
+      if (ReferenceEquals(other, null)) {
+        return false;
+      }
+      if (ReferenceEquals(other, this)) {
         return true;
       }
+      if (Size != other.Size) return false;
+      if (IntervalUs != other.IntervalUs) return false;
+      return true;
     }
 
-    public override void WriteTo(pb::ICodedOutputStream output) {
-      int size = SerializedSize;
-      string[] field_names = _responseParametersFieldNames;
-      if (hasSize) {
-        output.WriteInt32(1, field_names[1], Size);
-      }
-      if (hasIntervalUs) {
-        output.WriteInt32(2, field_names[0], IntervalUs);
-      }
-      UnknownFields.WriteTo(output);
+    public override int GetHashCode() {
+      int hash = 1;
+      if (Size != 0) hash ^= Size.GetHashCode();
+      if (IntervalUs != 0) hash ^= IntervalUs.GetHashCode();
+      return hash;
     }
 
-    private int memoizedSerializedSize = -1;
-    public override int SerializedSize {
-      get {
-        int size = memoizedSerializedSize;
-        if (size != -1) return size;
+    public override string ToString() {
+      return pb::JsonFormatter.Default.Format(this);
+    }
 
-        size = 0;
-        if (hasSize) {
-          size += pb::CodedOutputStream.ComputeInt32Size(1, Size);
-        }
-        if (hasIntervalUs) {
-          size += pb::CodedOutputStream.ComputeInt32Size(2, IntervalUs);
-        }
-        size += UnknownFields.SerializedSize;
-        memoizedSerializedSize = size;
-        return size;
+    public void WriteTo(pb::CodedOutputStream output) {
+      if (Size != 0) {
+        output.WriteRawTag(8);
+        output.WriteInt32(Size);
+      }
+      if (IntervalUs != 0) {
+        output.WriteRawTag(16);
+        output.WriteInt32(IntervalUs);
       }
     }
 
-    public static ResponseParameters ParseFrom(pb::ByteString data) {
-      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
-    }
-    public static ResponseParameters ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
-      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
-    }
-    public static ResponseParameters ParseFrom(byte[] data) {
-      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
-    }
-    public static ResponseParameters ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
-      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
-    }
-    public static ResponseParameters ParseFrom(global::System.IO.Stream input) {
-      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
-    }
-    public static ResponseParameters ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
-      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
-    }
-    public static ResponseParameters ParseDelimitedFrom(global::System.IO.Stream input) {
-      return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
-    }
-    public static ResponseParameters ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
-      return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
-    }
-    public static ResponseParameters ParseFrom(pb::ICodedInputStream input) {
-      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
-    }
-    public static ResponseParameters ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
-      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
-    }
-    private ResponseParameters MakeReadOnly() {
-      return this;
+    public int CalculateSize() {
+      int size = 0;
+      if (Size != 0) {
+        size += 1 + pb::CodedOutputStream.ComputeInt32Size(Size);
+      }
+      if (IntervalUs != 0) {
+        size += 1 + pb::CodedOutputStream.ComputeInt32Size(IntervalUs);
+      }
+      return size;
     }
 
-    public static Builder CreateBuilder() { return new Builder(); }
-    public override Builder ToBuilder() { return CreateBuilder(this); }
-    public override Builder CreateBuilderForType() { return new Builder(); }
-    public static Builder CreateBuilder(ResponseParameters prototype) {
-      return new Builder(prototype);
+    public void MergeFrom(ResponseParameters other) {
+      if (other == null) {
+        return;
+      }
+      if (other.Size != 0) {
+        Size = other.Size;
+      }
+      if (other.IntervalUs != 0) {
+        IntervalUs = other.IntervalUs;
+      }
     }
 
-    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
-    public sealed partial class Builder : pb::GeneratedBuilder<ResponseParameters, Builder> {
-      protected override Builder ThisBuilder {
-        get { return this; }
-      }
-      public Builder() {
-        result = DefaultInstance;
-        resultIsReadOnly = true;
-      }
-      internal Builder(ResponseParameters cloneFrom) {
-        result = cloneFrom;
-        resultIsReadOnly = true;
-      }
-
-      private bool resultIsReadOnly;
-      private ResponseParameters result;
-
-      private ResponseParameters PrepareBuilder() {
-        if (resultIsReadOnly) {
-          ResponseParameters original = result;
-          result = new ResponseParameters();
-          resultIsReadOnly = false;
-          MergeFrom(original);
-        }
-        return result;
-      }
-
-      public override bool IsInitialized {
-        get { return result.IsInitialized; }
-      }
-
-      protected override ResponseParameters MessageBeingBuilt {
-        get { return PrepareBuilder(); }
-      }
-
-      public override Builder Clear() {
-        result = DefaultInstance;
-        resultIsReadOnly = true;
-        return this;
-      }
-
-      public override Builder Clone() {
-        if (resultIsReadOnly) {
-          return new Builder(result);
-        } else {
-          return new Builder().MergeFrom(result);
-        }
-      }
-
-      public override pbd::MessageDescriptor DescriptorForType {
-        get { return global::grpc.testing.ResponseParameters.Descriptor; }
-      }
-
-      public override ResponseParameters DefaultInstanceForType {
-        get { return global::grpc.testing.ResponseParameters.DefaultInstance; }
-      }
-
-      public override ResponseParameters BuildPartial() {
-        if (resultIsReadOnly) {
-          return result;
-        }
-        resultIsReadOnly = true;
-        return result.MakeReadOnly();
-      }
-
-      public override Builder MergeFrom(pb::IMessage other) {
-        if (other is ResponseParameters) {
-          return MergeFrom((ResponseParameters) other);
-        } else {
-          base.MergeFrom(other);
-          return this;
-        }
-      }
-
-      public override Builder MergeFrom(ResponseParameters other) {
-        if (other == global::grpc.testing.ResponseParameters.DefaultInstance) return this;
-        PrepareBuilder();
-        if (other.HasSize) {
-          Size = other.Size;
-        }
-        if (other.HasIntervalUs) {
-          IntervalUs = other.IntervalUs;
-        }
-        this.MergeUnknownFields(other.UnknownFields);
-        return this;
-      }
-
-      public override Builder MergeFrom(pb::ICodedInputStream input) {
-        return MergeFrom(input, pb::ExtensionRegistry.Empty);
-      }
-
-      public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
-        PrepareBuilder();
-        pb::UnknownFieldSet.Builder unknownFields = null;
-        uint tag;
-        string field_name;
-        while (input.ReadTag(out tag, out field_name)) {
-          if(tag == 0 && field_name != null) {
-            int field_ordinal = global::System.Array.BinarySearch(_responseParametersFieldNames, field_name, global::System.StringComparer.Ordinal);
-            if(field_ordinal >= 0)
-              tag = _responseParametersFieldTags[field_ordinal];
-            else {
-              if (unknownFields == null) {
-                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
-              }
-              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);
-              continue;
-            }
+    public void MergeFrom(pb::CodedInputStream input) {
+      uint tag;
+      while ((tag = input.ReadTag()) != 0) {
+        switch(tag) {
+          default:
+            input.SkipLastField();
+            break;
+          case 8: {
+            Size = input.ReadInt32();
+            break;
           }
-          switch (tag) {
-            case 0: {
-              throw pb::InvalidProtocolBufferException.InvalidTag();
-            }
-            default: {
-              if (pb::WireFormat.IsEndGroupTag(tag)) {
-                if (unknownFields != null) {
-                  this.UnknownFields = unknownFields.Build();
-                }
-                return this;
-              }
-              if (unknownFields == null) {
-                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
-              }
-              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);
-              break;
-            }
-            case 8: {
-              result.hasSize = input.ReadInt32(ref result.size_);
-              break;
-            }
-            case 16: {
-              result.hasIntervalUs = input.ReadInt32(ref result.intervalUs_);
-              break;
-            }
+          case 16: {
+            IntervalUs = input.ReadInt32();
+            break;
           }
         }
-
-        if (unknownFields != null) {
-          this.UnknownFields = unknownFields.Build();
-        }
-        return this;
-      }
-
-
-      public bool HasSize {
-        get { return result.hasSize; }
-      }
-      public int Size {
-        get { return result.Size; }
-        set { SetSize(value); }
-      }
-      public Builder SetSize(int value) {
-        PrepareBuilder();
-        result.hasSize = true;
-        result.size_ = value;
-        return this;
-      }
-      public Builder ClearSize() {
-        PrepareBuilder();
-        result.hasSize = false;
-        result.size_ = 0;
-        return this;
-      }
-
-      public bool HasIntervalUs {
-        get { return result.hasIntervalUs; }
-      }
-      public int IntervalUs {
-        get { return result.IntervalUs; }
-        set { SetIntervalUs(value); }
-      }
-      public Builder SetIntervalUs(int value) {
-        PrepareBuilder();
-        result.hasIntervalUs = true;
-        result.intervalUs_ = value;
-        return this;
-      }
-      public Builder ClearIntervalUs() {
-        PrepareBuilder();
-        result.hasIntervalUs = false;
-        result.intervalUs_ = 0;
-        return this;
       }
     }
-    static ResponseParameters() {
-      object.ReferenceEquals(global::grpc.testing.Messages.Descriptor, null);
-    }
+
   }
 
   [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
-  public sealed partial class StreamingOutputCallRequest : pb::GeneratedMessage<StreamingOutputCallRequest, StreamingOutputCallRequest.Builder> {
-    private StreamingOutputCallRequest() { }
-    private static readonly StreamingOutputCallRequest defaultInstance = new StreamingOutputCallRequest().MakeReadOnly();
-    private static readonly string[] _streamingOutputCallRequestFieldNames = new string[] { "payload", "response_parameters", "response_type" };
-    private static readonly uint[] _streamingOutputCallRequestFieldTags = new uint[] { 26, 18, 8 };
-    public static StreamingOutputCallRequest DefaultInstance {
-      get { return defaultInstance; }
+  public sealed partial class StreamingOutputCallRequest : pb::IMessage<StreamingOutputCallRequest> {
+    private static readonly pb::MessageParser<StreamingOutputCallRequest> _parser = new pb::MessageParser<StreamingOutputCallRequest>(() => new StreamingOutputCallRequest());
+    public static pb::MessageParser<StreamingOutputCallRequest> Parser { get { return _parser; } }
+
+    public static pbr::MessageDescriptor Descriptor {
+      get { return global::Grpc.Testing.Messages.Descriptor.MessageTypes[6]; }
     }
 
-    public override StreamingOutputCallRequest DefaultInstanceForType {
-      get { return DefaultInstance; }
+    pbr::MessageDescriptor pb::IMessage.Descriptor {
+      get { return Descriptor; }
     }
 
-    protected override StreamingOutputCallRequest ThisMessage {
-      get { return this; }
+    public StreamingOutputCallRequest() {
+      OnConstruction();
     }
 
-    public static pbd::MessageDescriptor Descriptor {
-      get { return global::grpc.testing.Messages.internal__static_grpc_testing_StreamingOutputCallRequest__Descriptor; }
+    partial void OnConstruction();
+
+    public StreamingOutputCallRequest(StreamingOutputCallRequest other) : this() {
+      responseType_ = other.responseType_;
+      responseParameters_ = other.responseParameters_.Clone();
+      Payload = other.payload_ != null ? other.Payload.Clone() : null;
     }
 
-    protected override pb::FieldAccess.FieldAccessorTable<StreamingOutputCallRequest, StreamingOutputCallRequest.Builder> InternalFieldAccessors {
-      get { return global::grpc.testing.Messages.internal__static_grpc_testing_StreamingOutputCallRequest__FieldAccessorTable; }
+    public StreamingOutputCallRequest Clone() {
+      return new StreamingOutputCallRequest(this);
     }
 
     public const int ResponseTypeFieldNumber = 1;
-    private bool hasResponseType;
-    private global::grpc.testing.PayloadType responseType_ = global::grpc.testing.PayloadType.COMPRESSABLE;
-    public bool HasResponseType {
-      get { return hasResponseType; }
-    }
-    public global::grpc.testing.PayloadType ResponseType {
+    private global::Grpc.Testing.PayloadType responseType_ = global::Grpc.Testing.PayloadType.COMPRESSABLE;
+    public global::Grpc.Testing.PayloadType ResponseType {
       get { return responseType_; }
+      set {
+        responseType_ = value;
+      }
     }
 
     public const int ResponseParametersFieldNumber = 2;
-    private pbc::PopsicleList<global::grpc.testing.ResponseParameters> responseParameters_ = new pbc::PopsicleList<global::grpc.testing.ResponseParameters>();
-    public scg::IList<global::grpc.testing.ResponseParameters> ResponseParametersList {
+    private static readonly pb::FieldCodec<global::Grpc.Testing.ResponseParameters> _repeated_responseParameters_codec
+        = pb::FieldCodec.ForMessage(18, global::Grpc.Testing.ResponseParameters.Parser);
+    private readonly pbc::RepeatedField<global::Grpc.Testing.ResponseParameters> responseParameters_ = new pbc::RepeatedField<global::Grpc.Testing.ResponseParameters>();
+    public pbc::RepeatedField<global::Grpc.Testing.ResponseParameters> ResponseParameters {
       get { return responseParameters_; }
     }
-    public int ResponseParametersCount {
-      get { return responseParameters_.Count; }
-    }
-    public global::grpc.testing.ResponseParameters GetResponseParameters(int index) {
-      return responseParameters_[index];
-    }
 
     public const int PayloadFieldNumber = 3;
-    private bool hasPayload;
-    private global::grpc.testing.Payload payload_;
-    public bool HasPayload {
-      get { return hasPayload; }
-    }
-    public global::grpc.testing.Payload Payload {
-      get { return payload_ ?? global::grpc.testing.Payload.DefaultInstance; }
+    private global::Grpc.Testing.Payload payload_;
+    public global::Grpc.Testing.Payload Payload {
+      get { return payload_; }
+      set {
+        payload_ = value;
+      }
     }
 
-    public override bool IsInitialized {
-      get {
+    public override bool Equals(object other) {
+      return Equals(other as StreamingOutputCallRequest);
+    }
+
+    public bool Equals(StreamingOutputCallRequest other) {
+      if (ReferenceEquals(other, null)) {
+        return false;
+      }
+      if (ReferenceEquals(other, this)) {
         return true;
       }
+      if (ResponseType != other.ResponseType) return false;
+      if(!responseParameters_.Equals(other.responseParameters_)) return false;
+      if (!object.Equals(Payload, other.Payload)) return false;
+      return true;
     }
 
-    public override void WriteTo(pb::ICodedOutputStream output) {
-      int size = SerializedSize;
-      string[] field_names = _streamingOutputCallRequestFieldNames;
-      if (hasResponseType) {
-        output.WriteEnum(1, field_names[2], (int) ResponseType, ResponseType);
-      }
-      if (responseParameters_.Count > 0) {
-        output.WriteMessageArray(2, field_names[1], responseParameters_);
-      }
-      if (hasPayload) {
-        output.WriteMessage(3, field_names[0], Payload);
-      }
-      UnknownFields.WriteTo(output);
+    public override int GetHashCode() {
+      int hash = 1;
+      if (ResponseType != global::Grpc.Testing.PayloadType.COMPRESSABLE) hash ^= ResponseType.GetHashCode();
+      hash ^= responseParameters_.GetHashCode();
+      if (payload_ != null) hash ^= Payload.GetHashCode();
+      return hash;
     }
 
-    private int memoizedSerializedSize = -1;
-    public override int SerializedSize {
-      get {
-        int size = memoizedSerializedSize;
-        if (size != -1) return size;
+    public override string ToString() {
+      return pb::JsonFormatter.Default.Format(this);
+    }
 
-        size = 0;
-        if (hasResponseType) {
-          size += pb::CodedOutputStream.ComputeEnumSize(1, (int) ResponseType);
+    public void WriteTo(pb::CodedOutputStream output) {
+      if (ResponseType != global::Grpc.Testing.PayloadType.COMPRESSABLE) {
+        output.WriteRawTag(8);
+        output.WriteEnum((int) ResponseType);
+      }
+      responseParameters_.WriteTo(output, _repeated_responseParameters_codec);
+      if (payload_ != null) {
+        output.WriteRawTag(26);
+        output.WriteMessage(Payload);
+      }
+    }
+
+    public int CalculateSize() {
+      int size = 0;
+      if (ResponseType != global::Grpc.Testing.PayloadType.COMPRESSABLE) {
+        size += 1 + pb::CodedOutputStream.ComputeEnumSize((int) ResponseType);
+      }
+      size += responseParameters_.CalculateSize(_repeated_responseParameters_codec);
+      if (payload_ != null) {
+        size += 1 + pb::CodedOutputStream.ComputeMessageSize(Payload);
+      }
+      return size;
+    }
+
+    public void MergeFrom(StreamingOutputCallRequest other) {
+      if (other == null) {
+        return;
+      }
+      if (other.ResponseType != global::Grpc.Testing.PayloadType.COMPRESSABLE) {
+        ResponseType = other.ResponseType;
+      }
+      responseParameters_.Add(other.responseParameters_);
+      if (other.payload_ != null) {
+        if (payload_ == null) {
+          payload_ = new global::Grpc.Testing.Payload();
         }
-        foreach (global::grpc.testing.ResponseParameters element in ResponseParametersList) {
-          size += pb::CodedOutputStream.ComputeMessageSize(2, element);
-        }
-        if (hasPayload) {
-          size += pb::CodedOutputStream.ComputeMessageSize(3, Payload);
-        }
-        size += UnknownFields.SerializedSize;
-        memoizedSerializedSize = size;
-        return size;
+        Payload.MergeFrom(other.Payload);
       }
     }
 
-    public static StreamingOutputCallRequest ParseFrom(pb::ByteString data) {
-      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
-    }
-    public static StreamingOutputCallRequest ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
-      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
-    }
-    public static StreamingOutputCallRequest ParseFrom(byte[] data) {
-      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
-    }
-    public static StreamingOutputCallRequest ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
-      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
-    }
-    public static StreamingOutputCallRequest ParseFrom(global::System.IO.Stream input) {
-      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
-    }
-    public static StreamingOutputCallRequest ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
-      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
-    }
-    public static StreamingOutputCallRequest ParseDelimitedFrom(global::System.IO.Stream input) {
-      return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
-    }
-    public static StreamingOutputCallRequest ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
-      return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
-    }
-    public static StreamingOutputCallRequest ParseFrom(pb::ICodedInputStream input) {
-      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
-    }
-    public static StreamingOutputCallRequest ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
-      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
-    }
-    private StreamingOutputCallRequest MakeReadOnly() {
-      responseParameters_.MakeReadOnly();
-      return this;
-    }
-
-    public static Builder CreateBuilder() { return new Builder(); }
-    public override Builder ToBuilder() { return CreateBuilder(this); }
-    public override Builder CreateBuilderForType() { return new Builder(); }
-    public static Builder CreateBuilder(StreamingOutputCallRequest prototype) {
-      return new Builder(prototype);
-    }
-
-    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
-    public sealed partial class Builder : pb::GeneratedBuilder<StreamingOutputCallRequest, Builder> {
-      protected override Builder ThisBuilder {
-        get { return this; }
-      }
-      public Builder() {
-        result = DefaultInstance;
-        resultIsReadOnly = true;
-      }
-      internal Builder(StreamingOutputCallRequest cloneFrom) {
-        result = cloneFrom;
-        resultIsReadOnly = true;
-      }
-
-      private bool resultIsReadOnly;
-      private StreamingOutputCallRequest result;
-
-      private StreamingOutputCallRequest PrepareBuilder() {
-        if (resultIsReadOnly) {
-          StreamingOutputCallRequest original = result;
-          result = new StreamingOutputCallRequest();
-          resultIsReadOnly = false;
-          MergeFrom(original);
-        }
-        return result;
-      }
-
-      public override bool IsInitialized {
-        get { return result.IsInitialized; }
-      }
-
-      protected override StreamingOutputCallRequest MessageBeingBuilt {
-        get { return PrepareBuilder(); }
-      }
-
-      public override Builder Clear() {
-        result = DefaultInstance;
-        resultIsReadOnly = true;
-        return this;
-      }
-
-      public override Builder Clone() {
-        if (resultIsReadOnly) {
-          return new Builder(result);
-        } else {
-          return new Builder().MergeFrom(result);
-        }
-      }
-
-      public override pbd::MessageDescriptor DescriptorForType {
-        get { return global::grpc.testing.StreamingOutputCallRequest.Descriptor; }
-      }
-
-      public override StreamingOutputCallRequest DefaultInstanceForType {
-        get { return global::grpc.testing.StreamingOutputCallRequest.DefaultInstance; }
-      }
-
-      public override StreamingOutputCallRequest BuildPartial() {
-        if (resultIsReadOnly) {
-          return result;
-        }
-        resultIsReadOnly = true;
-        return result.MakeReadOnly();
-      }
-
-      public override Builder MergeFrom(pb::IMessage other) {
-        if (other is StreamingOutputCallRequest) {
-          return MergeFrom((StreamingOutputCallRequest) other);
-        } else {
-          base.MergeFrom(other);
-          return this;
-        }
-      }
-
-      public override Builder MergeFrom(StreamingOutputCallRequest other) {
-        if (other == global::grpc.testing.StreamingOutputCallRequest.DefaultInstance) return this;
-        PrepareBuilder();
-        if (other.HasResponseType) {
-          ResponseType = other.ResponseType;
-        }
-        if (other.responseParameters_.Count != 0) {
-          result.responseParameters_.Add(other.responseParameters_);
-        }
-        if (other.HasPayload) {
-          MergePayload(other.Payload);
-        }
-        this.MergeUnknownFields(other.UnknownFields);
-        return this;
-      }
-
-      public override Builder MergeFrom(pb::ICodedInputStream input) {
-        return MergeFrom(input, pb::ExtensionRegistry.Empty);
-      }
-
-      public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
-        PrepareBuilder();
-        pb::UnknownFieldSet.Builder unknownFields = null;
-        uint tag;
-        string field_name;
-        while (input.ReadTag(out tag, out field_name)) {
-          if(tag == 0 && field_name != null) {
-            int field_ordinal = global::System.Array.BinarySearch(_streamingOutputCallRequestFieldNames, field_name, global::System.StringComparer.Ordinal);
-            if(field_ordinal >= 0)
-              tag = _streamingOutputCallRequestFieldTags[field_ordinal];
-            else {
-              if (unknownFields == null) {
-                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
-              }
-              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);
-              continue;
-            }
+    public void MergeFrom(pb::CodedInputStream input) {
+      uint tag;
+      while ((tag = input.ReadTag()) != 0) {
+        switch(tag) {
+          default:
+            input.SkipLastField();
+            break;
+          case 8: {
+            responseType_ = (global::Grpc.Testing.PayloadType) input.ReadEnum();
+            break;
           }
-          switch (tag) {
-            case 0: {
-              throw pb::InvalidProtocolBufferException.InvalidTag();
+          case 18: {
+            responseParameters_.AddEntriesFrom(input, _repeated_responseParameters_codec);
+            break;
+          }
+          case 26: {
+            if (payload_ == null) {
+              payload_ = new global::Grpc.Testing.Payload();
             }
-            default: {
-              if (pb::WireFormat.IsEndGroupTag(tag)) {
-                if (unknownFields != null) {
-                  this.UnknownFields = unknownFields.Build();
-                }
-                return this;
-              }
-              if (unknownFields == null) {
-                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
-              }
-              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);
-              break;
-            }
-            case 8: {
-              object unknown;
-              if(input.ReadEnum(ref result.responseType_, out unknown)) {
-                result.hasResponseType = true;
-              } else if(unknown is int) {
-                if (unknownFields == null) {
-                  unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
-                }
-                unknownFields.MergeVarintField(1, (ulong)(int)unknown);
-              }
-              break;
-            }
-            case 18: {
-              input.ReadMessageArray(tag, field_name, result.responseParameters_, global::grpc.testing.ResponseParameters.DefaultInstance, extensionRegistry);
-              break;
-            }
-            case 26: {
-              global::grpc.testing.Payload.Builder subBuilder = global::grpc.testing.Payload.CreateBuilder();
-              if (result.hasPayload) {
-                subBuilder.MergeFrom(Payload);
-              }
-              input.ReadMessage(subBuilder, extensionRegistry);
-              Payload = subBuilder.BuildPartial();
-              break;
-            }
+            input.ReadMessage(payload_);
+            break;
           }
         }
-
-        if (unknownFields != null) {
-          this.UnknownFields = unknownFields.Build();
-        }
-        return this;
-      }
-
-
-      public bool HasResponseType {
-       get { return result.hasResponseType; }
-      }
-      public global::grpc.testing.PayloadType ResponseType {
-        get { return result.ResponseType; }
-        set { SetResponseType(value); }
-      }
-      public Builder SetResponseType(global::grpc.testing.PayloadType value) {
-        PrepareBuilder();
-        result.hasResponseType = true;
-        result.responseType_ = value;
-        return this;
-      }
-      public Builder ClearResponseType() {
-        PrepareBuilder();
-        result.hasResponseType = false;
-        result.responseType_ = global::grpc.testing.PayloadType.COMPRESSABLE;
-        return this;
-      }
-
-      public pbc::IPopsicleList<global::grpc.testing.ResponseParameters> ResponseParametersList {
-        get { return PrepareBuilder().responseParameters_; }
-      }
-      public int ResponseParametersCount {
-        get { return result.ResponseParametersCount; }
-      }
-      public global::grpc.testing.ResponseParameters GetResponseParameters(int index) {
-        return result.GetResponseParameters(index);
-      }
-      public Builder SetResponseParameters(int index, global::grpc.testing.ResponseParameters value) {
-        pb::ThrowHelper.ThrowIfNull(value, "value");
-        PrepareBuilder();
-        result.responseParameters_[index] = value;
-        return this;
-      }
-      public Builder SetResponseParameters(int index, global::grpc.testing.ResponseParameters.Builder builderForValue) {
-        pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
-        PrepareBuilder();
-        result.responseParameters_[index] = builderForValue.Build();
-        return this;
-      }
-      public Builder AddResponseParameters(global::grpc.testing.ResponseParameters value) {
-        pb::ThrowHelper.ThrowIfNull(value, "value");
-        PrepareBuilder();
-        result.responseParameters_.Add(value);
-        return this;
-      }
-      public Builder AddResponseParameters(global::grpc.testing.ResponseParameters.Builder builderForValue) {
-        pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
-        PrepareBuilder();
-        result.responseParameters_.Add(builderForValue.Build());
-        return this;
-      }
-      public Builder AddRangeResponseParameters(scg::IEnumerable<global::grpc.testing.ResponseParameters> values) {
-        PrepareBuilder();
-        result.responseParameters_.Add(values);
-        return this;
-      }
-      public Builder ClearResponseParameters() {
-        PrepareBuilder();
-        result.responseParameters_.Clear();
-        return this;
-      }
-
-      public bool HasPayload {
-       get { return result.hasPayload; }
-      }
-      public global::grpc.testing.Payload Payload {
-        get { return result.Payload; }
-        set { SetPayload(value); }
-      }
-      public Builder SetPayload(global::grpc.testing.Payload value) {
-        pb::ThrowHelper.ThrowIfNull(value, "value");
-        PrepareBuilder();
-        result.hasPayload = true;
-        result.payload_ = value;
-        return this;
-      }
-      public Builder SetPayload(global::grpc.testing.Payload.Builder builderForValue) {
-        pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
-        PrepareBuilder();
-        result.hasPayload = true;
-        result.payload_ = builderForValue.Build();
-        return this;
-      }
-      public Builder MergePayload(global::grpc.testing.Payload value) {
-        pb::ThrowHelper.ThrowIfNull(value, "value");
-        PrepareBuilder();
-        if (result.hasPayload &&
-            result.payload_ != global::grpc.testing.Payload.DefaultInstance) {
-            result.payload_ = global::grpc.testing.Payload.CreateBuilder(result.payload_).MergeFrom(value).BuildPartial();
-        } else {
-          result.payload_ = value;
-        }
-        result.hasPayload = true;
-        return this;
-      }
-      public Builder ClearPayload() {
-        PrepareBuilder();
-        result.hasPayload = false;
-        result.payload_ = null;
-        return this;
       }
     }
-    static StreamingOutputCallRequest() {
-      object.ReferenceEquals(global::grpc.testing.Messages.Descriptor, null);
-    }
+
   }
 
   [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
-  public sealed partial class StreamingOutputCallResponse : pb::GeneratedMessage<StreamingOutputCallResponse, StreamingOutputCallResponse.Builder> {
-    private StreamingOutputCallResponse() { }
-    private static readonly StreamingOutputCallResponse defaultInstance = new StreamingOutputCallResponse().MakeReadOnly();
-    private static readonly string[] _streamingOutputCallResponseFieldNames = new string[] { "payload" };
-    private static readonly uint[] _streamingOutputCallResponseFieldTags = new uint[] { 10 };
-    public static StreamingOutputCallResponse DefaultInstance {
-      get { return defaultInstance; }
+  public sealed partial class StreamingOutputCallResponse : pb::IMessage<StreamingOutputCallResponse> {
+    private static readonly pb::MessageParser<StreamingOutputCallResponse> _parser = new pb::MessageParser<StreamingOutputCallResponse>(() => new StreamingOutputCallResponse());
+    public static pb::MessageParser<StreamingOutputCallResponse> Parser { get { return _parser; } }
+
+    public static pbr::MessageDescriptor Descriptor {
+      get { return global::Grpc.Testing.Messages.Descriptor.MessageTypes[7]; }
     }
 
-    public override StreamingOutputCallResponse DefaultInstanceForType {
-      get { return DefaultInstance; }
+    pbr::MessageDescriptor pb::IMessage.Descriptor {
+      get { return Descriptor; }
     }
 
-    protected override StreamingOutputCallResponse ThisMessage {
-      get { return this; }
+    public StreamingOutputCallResponse() {
+      OnConstruction();
     }
 
-    public static pbd::MessageDescriptor Descriptor {
-      get { return global::grpc.testing.Messages.internal__static_grpc_testing_StreamingOutputCallResponse__Descriptor; }
+    partial void OnConstruction();
+
+    public StreamingOutputCallResponse(StreamingOutputCallResponse other) : this() {
+      Payload = other.payload_ != null ? other.Payload.Clone() : null;
     }
 
-    protected override pb::FieldAccess.FieldAccessorTable<StreamingOutputCallResponse, StreamingOutputCallResponse.Builder> InternalFieldAccessors {
-      get { return global::grpc.testing.Messages.internal__static_grpc_testing_StreamingOutputCallResponse__FieldAccessorTable; }
+    public StreamingOutputCallResponse Clone() {
+      return new StreamingOutputCallResponse(this);
     }
 
     public const int PayloadFieldNumber = 1;
-    private bool hasPayload;
-    private global::grpc.testing.Payload payload_;
-    public bool HasPayload {
-      get { return hasPayload; }
-    }
-    public global::grpc.testing.Payload Payload {
-      get { return payload_ ?? global::grpc.testing.Payload.DefaultInstance; }
+    private global::Grpc.Testing.Payload payload_;
+    public global::Grpc.Testing.Payload Payload {
+      get { return payload_; }
+      set {
+        payload_ = value;
+      }
     }
 
-    public override bool IsInitialized {
-      get {
+    public override bool Equals(object other) {
+      return Equals(other as StreamingOutputCallResponse);
+    }
+
+    public bool Equals(StreamingOutputCallResponse other) {
+      if (ReferenceEquals(other, null)) {
+        return false;
+      }
+      if (ReferenceEquals(other, this)) {
         return true;
       }
+      if (!object.Equals(Payload, other.Payload)) return false;
+      return true;
     }
 
-    public override void WriteTo(pb::ICodedOutputStream output) {
-      int size = SerializedSize;
-      string[] field_names = _streamingOutputCallResponseFieldNames;
-      if (hasPayload) {
-        output.WriteMessage(1, field_names[0], Payload);
+    public override int GetHashCode() {
+      int hash = 1;
+      if (payload_ != null) hash ^= Payload.GetHashCode();
+      return hash;
+    }
+
+    public override string ToString() {
+      return pb::JsonFormatter.Default.Format(this);
+    }
+
+    public void WriteTo(pb::CodedOutputStream output) {
+      if (payload_ != null) {
+        output.WriteRawTag(10);
+        output.WriteMessage(Payload);
       }
-      UnknownFields.WriteTo(output);
     }
 
-    private int memoizedSerializedSize = -1;
-    public override int SerializedSize {
-      get {
-        int size = memoizedSerializedSize;
-        if (size != -1) return size;
+    public int CalculateSize() {
+      int size = 0;
+      if (payload_ != null) {
+        size += 1 + pb::CodedOutputStream.ComputeMessageSize(Payload);
+      }
+      return size;
+    }
 
-        size = 0;
-        if (hasPayload) {
-          size += pb::CodedOutputStream.ComputeMessageSize(1, Payload);
+    public void MergeFrom(StreamingOutputCallResponse other) {
+      if (other == null) {
+        return;
+      }
+      if (other.payload_ != null) {
+        if (payload_ == null) {
+          payload_ = new global::Grpc.Testing.Payload();
         }
-        size += UnknownFields.SerializedSize;
-        memoizedSerializedSize = size;
-        return size;
+        Payload.MergeFrom(other.Payload);
       }
     }
 
-    public static StreamingOutputCallResponse ParseFrom(pb::ByteString data) {
-      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
-    }
-    public static StreamingOutputCallResponse ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
-      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
-    }
-    public static StreamingOutputCallResponse ParseFrom(byte[] data) {
-      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
-    }
-    public static StreamingOutputCallResponse ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
-      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
-    }
-    public static StreamingOutputCallResponse ParseFrom(global::System.IO.Stream input) {
-      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
-    }
-    public static StreamingOutputCallResponse ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
-      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
-    }
-    public static StreamingOutputCallResponse ParseDelimitedFrom(global::System.IO.Stream input) {
-      return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
-    }
-    public static StreamingOutputCallResponse ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
-      return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
-    }
-    public static StreamingOutputCallResponse ParseFrom(pb::ICodedInputStream input) {
-      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
-    }
-    public static StreamingOutputCallResponse ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
-      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
-    }
-    private StreamingOutputCallResponse MakeReadOnly() {
-      return this;
-    }
-
-    public static Builder CreateBuilder() { return new Builder(); }
-    public override Builder ToBuilder() { return CreateBuilder(this); }
-    public override Builder CreateBuilderForType() { return new Builder(); }
-    public static Builder CreateBuilder(StreamingOutputCallResponse prototype) {
-      return new Builder(prototype);
-    }
-
-    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
-    public sealed partial class Builder : pb::GeneratedBuilder<StreamingOutputCallResponse, Builder> {
-      protected override Builder ThisBuilder {
-        get { return this; }
-      }
-      public Builder() {
-        result = DefaultInstance;
-        resultIsReadOnly = true;
-      }
-      internal Builder(StreamingOutputCallResponse cloneFrom) {
-        result = cloneFrom;
-        resultIsReadOnly = true;
-      }
-
-      private bool resultIsReadOnly;
-      private StreamingOutputCallResponse result;
-
-      private StreamingOutputCallResponse PrepareBuilder() {
-        if (resultIsReadOnly) {
-          StreamingOutputCallResponse original = result;
-          result = new StreamingOutputCallResponse();
-          resultIsReadOnly = false;
-          MergeFrom(original);
-        }
-        return result;
-      }
-
-      public override bool IsInitialized {
-        get { return result.IsInitialized; }
-      }
-
-      protected override StreamingOutputCallResponse MessageBeingBuilt {
-        get { return PrepareBuilder(); }
-      }
-
-      public override Builder Clear() {
-        result = DefaultInstance;
-        resultIsReadOnly = true;
-        return this;
-      }
-
-      public override Builder Clone() {
-        if (resultIsReadOnly) {
-          return new Builder(result);
-        } else {
-          return new Builder().MergeFrom(result);
-        }
-      }
-
-      public override pbd::MessageDescriptor DescriptorForType {
-        get { return global::grpc.testing.StreamingOutputCallResponse.Descriptor; }
-      }
-
-      public override StreamingOutputCallResponse DefaultInstanceForType {
-        get { return global::grpc.testing.StreamingOutputCallResponse.DefaultInstance; }
-      }
-
-      public override StreamingOutputCallResponse BuildPartial() {
-        if (resultIsReadOnly) {
-          return result;
-        }
-        resultIsReadOnly = true;
-        return result.MakeReadOnly();
-      }
-
-      public override Builder MergeFrom(pb::IMessage other) {
-        if (other is StreamingOutputCallResponse) {
-          return MergeFrom((StreamingOutputCallResponse) other);
-        } else {
-          base.MergeFrom(other);
-          return this;
-        }
-      }
-
-      public override Builder MergeFrom(StreamingOutputCallResponse other) {
-        if (other == global::grpc.testing.StreamingOutputCallResponse.DefaultInstance) return this;
-        PrepareBuilder();
-        if (other.HasPayload) {
-          MergePayload(other.Payload);
-        }
-        this.MergeUnknownFields(other.UnknownFields);
-        return this;
-      }
-
-      public override Builder MergeFrom(pb::ICodedInputStream input) {
-        return MergeFrom(input, pb::ExtensionRegistry.Empty);
-      }
-
-      public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
-        PrepareBuilder();
-        pb::UnknownFieldSet.Builder unknownFields = null;
-        uint tag;
-        string field_name;
-        while (input.ReadTag(out tag, out field_name)) {
-          if(tag == 0 && field_name != null) {
-            int field_ordinal = global::System.Array.BinarySearch(_streamingOutputCallResponseFieldNames, field_name, global::System.StringComparer.Ordinal);
-            if(field_ordinal >= 0)
-              tag = _streamingOutputCallResponseFieldTags[field_ordinal];
-            else {
-              if (unknownFields == null) {
-                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
-              }
-              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);
-              continue;
+    public void MergeFrom(pb::CodedInputStream input) {
+      uint tag;
+      while ((tag = input.ReadTag()) != 0) {
+        switch(tag) {
+          default:
+            input.SkipLastField();
+            break;
+          case 10: {
+            if (payload_ == null) {
+              payload_ = new global::Grpc.Testing.Payload();
             }
-          }
-          switch (tag) {
-            case 0: {
-              throw pb::InvalidProtocolBufferException.InvalidTag();
-            }
-            default: {
-              if (pb::WireFormat.IsEndGroupTag(tag)) {
-                if (unknownFields != null) {
-                  this.UnknownFields = unknownFields.Build();
-                }
-                return this;
-              }
-              if (unknownFields == null) {
-                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
-              }
-              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);
-              break;
-            }
-            case 10: {
-              global::grpc.testing.Payload.Builder subBuilder = global::grpc.testing.Payload.CreateBuilder();
-              if (result.hasPayload) {
-                subBuilder.MergeFrom(Payload);
-              }
-              input.ReadMessage(subBuilder, extensionRegistry);
-              Payload = subBuilder.BuildPartial();
-              break;
-            }
+            input.ReadMessage(payload_);
+            break;
           }
         }
-
-        if (unknownFields != null) {
-          this.UnknownFields = unknownFields.Build();
-        }
-        return this;
-      }
-
-
-      public bool HasPayload {
-       get { return result.hasPayload; }
-      }
-      public global::grpc.testing.Payload Payload {
-        get { return result.Payload; }
-        set { SetPayload(value); }
-      }
-      public Builder SetPayload(global::grpc.testing.Payload value) {
-        pb::ThrowHelper.ThrowIfNull(value, "value");
-        PrepareBuilder();
-        result.hasPayload = true;
-        result.payload_ = value;
-        return this;
-      }
-      public Builder SetPayload(global::grpc.testing.Payload.Builder builderForValue) {
-        pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
-        PrepareBuilder();
-        result.hasPayload = true;
-        result.payload_ = builderForValue.Build();
-        return this;
-      }
-      public Builder MergePayload(global::grpc.testing.Payload value) {
-        pb::ThrowHelper.ThrowIfNull(value, "value");
-        PrepareBuilder();
-        if (result.hasPayload &&
-            result.payload_ != global::grpc.testing.Payload.DefaultInstance) {
-            result.payload_ = global::grpc.testing.Payload.CreateBuilder(result.payload_).MergeFrom(value).BuildPartial();
-        } else {
-          result.payload_ = value;
-        }
-        result.hasPayload = true;
-        return this;
-      }
-      public Builder ClearPayload() {
-        PrepareBuilder();
-        result.hasPayload = false;
-        result.payload_ = null;
-        return this;
       }
     }
-    static StreamingOutputCallResponse() {
-      object.ReferenceEquals(global::grpc.testing.Messages.Descriptor, null);
-    }
+
   }
 
   #endregion
diff --git a/src/csharp/Grpc.IntegrationTesting/SslCredentialsTest.cs b/src/csharp/Grpc.IntegrationTesting/SslCredentialsTest.cs
index 8427953..37b2518 100644
--- a/src/csharp/Grpc.IntegrationTesting/SslCredentialsTest.cs
+++ b/src/csharp/Grpc.IntegrationTesting/SslCredentialsTest.cs
@@ -37,9 +37,9 @@
 using System.Linq;
 using System.Threading;
 using System.Threading.Tasks;
-using grpc.testing;
 using Grpc.Core;
 using Grpc.Core.Utils;
+using Grpc.Testing;
 using NUnit.Framework;
 
 namespace Grpc.IntegrationTesting
@@ -92,7 +92,7 @@
         [Test]
         public void AuthenticatedClientAndServer()
         {
-            var response = client.UnaryCall(SimpleRequest.CreateBuilder().SetResponseSize(10).Build());
+            var response = client.UnaryCall(new SimpleRequest { ResponseSize = 10 });
             Assert.AreEqual(10, response.Payload.Body.Length);
         }
     }
diff --git a/src/csharp/Grpc.IntegrationTesting/Test.cs b/src/csharp/Grpc.IntegrationTesting/Test.cs
new file mode 100644
index 0000000..466ec57
--- /dev/null
+++ b/src/csharp/Grpc.IntegrationTesting/Test.cs
@@ -0,0 +1,48 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: test.proto
+#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 Grpc.Testing {
+
+  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+  public static partial class Test {
+
+    #region Descriptor
+    public static pbr::FileDescriptor Descriptor {
+      get { return descriptor; }
+    }
+    private static pbr::FileDescriptor descriptor;
+
+    static Test() {
+      byte[] descriptorData = global::System.Convert.FromBase64String(
+          string.Concat(
+            "Cgp0ZXN0LnByb3RvEgxncnBjLnRlc3RpbmcaC2VtcHR5LnByb3RvGg5tZXNz", 
+            "YWdlcy5wcm90bzK7BAoLVGVzdFNlcnZpY2USNQoJRW1wdHlDYWxsEhMuZ3Jw", 
+            "Yy50ZXN0aW5nLkVtcHR5GhMuZ3JwYy50ZXN0aW5nLkVtcHR5EkYKCVVuYXJ5", 
+            "Q2FsbBIbLmdycGMudGVzdGluZy5TaW1wbGVSZXF1ZXN0GhwuZ3JwYy50ZXN0", 
+            "aW5nLlNpbXBsZVJlc3BvbnNlEmwKE1N0cmVhbWluZ091dHB1dENhbGwSKC5n", 
+            "cnBjLnRlc3RpbmcuU3RyZWFtaW5nT3V0cHV0Q2FsbFJlcXVlc3QaKS5ncnBj", 
+            "LnRlc3RpbmcuU3RyZWFtaW5nT3V0cHV0Q2FsbFJlc3BvbnNlMAESaQoSU3Ry", 
+            "ZWFtaW5nSW5wdXRDYWxsEicuZ3JwYy50ZXN0aW5nLlN0cmVhbWluZ0lucHV0", 
+            "Q2FsbFJlcXVlc3QaKC5ncnBjLnRlc3RpbmcuU3RyZWFtaW5nSW5wdXRDYWxs", 
+            "UmVzcG9uc2UoARJpCg5GdWxsRHVwbGV4Q2FsbBIoLmdycGMudGVzdGluZy5T", 
+            "dHJlYW1pbmdPdXRwdXRDYWxsUmVxdWVzdBopLmdycGMudGVzdGluZy5TdHJl", 
+            "YW1pbmdPdXRwdXRDYWxsUmVzcG9uc2UoATABEmkKDkhhbGZEdXBsZXhDYWxs", 
+            "EiguZ3JwYy50ZXN0aW5nLlN0cmVhbWluZ091dHB1dENhbGxSZXF1ZXN0Giku", 
+            "Z3JwYy50ZXN0aW5nLlN0cmVhbWluZ091dHB1dENhbGxSZXNwb25zZSgBMAFi", 
+            "BnByb3RvMw=="));
+      descriptor = pbr::FileDescriptor.InternalBuildGeneratedFileFrom(descriptorData,
+          new pbr::FileDescriptor[] { global::Grpc.Testing.Proto.Empty.Descriptor, global::Grpc.Testing.Messages.Descriptor, },
+          new pbr::GeneratedCodeInfo(null, null));
+    }
+    #endregion
+
+  }
+}
+
+#endregion Designer generated code
diff --git a/src/csharp/Grpc.IntegrationTesting/TestCredentials.cs b/src/csharp/Grpc.IntegrationTesting/TestCredentials.cs
index da0b7fb..7a48d6e 100644
--- a/src/csharp/Grpc.IntegrationTesting/TestCredentials.cs
+++ b/src/csharp/Grpc.IntegrationTesting/TestCredentials.cs
@@ -37,8 +37,6 @@
 using System.IO;
 using System.Text.RegularExpressions;
 using System.Threading.Tasks;
-using Google.ProtocolBuffers;
-using grpc.testing;
 using Grpc.Core;
 using Grpc.Core.Utils;
 using NUnit.Framework;
diff --git a/src/csharp/Grpc.IntegrationTesting/TestGrpc.cs b/src/csharp/Grpc.IntegrationTesting/TestGrpc.cs
index 697acb5..f63e148 100644
--- a/src/csharp/Grpc.IntegrationTesting/TestGrpc.cs
+++ b/src/csharp/Grpc.IntegrationTesting/TestGrpc.cs
@@ -7,91 +7,97 @@
 using System.Threading.Tasks;
 using Grpc.Core;
 
-namespace grpc.testing {
+namespace Grpc.Testing {
   public static class TestService
   {
     static readonly string __ServiceName = "grpc.testing.TestService";
 
-    static readonly Marshaller<global::grpc.testing.Empty> __Marshaller_Empty = Marshallers.Create((arg) => arg.ToByteArray(), global::grpc.testing.Empty.ParseFrom);
-    static readonly Marshaller<global::grpc.testing.SimpleRequest> __Marshaller_SimpleRequest = Marshallers.Create((arg) => arg.ToByteArray(), global::grpc.testing.SimpleRequest.ParseFrom);
-    static readonly Marshaller<global::grpc.testing.SimpleResponse> __Marshaller_SimpleResponse = Marshallers.Create((arg) => arg.ToByteArray(), global::grpc.testing.SimpleResponse.ParseFrom);
-    static readonly Marshaller<global::grpc.testing.StreamingOutputCallRequest> __Marshaller_StreamingOutputCallRequest = Marshallers.Create((arg) => arg.ToByteArray(), global::grpc.testing.StreamingOutputCallRequest.ParseFrom);
-    static readonly Marshaller<global::grpc.testing.StreamingOutputCallResponse> __Marshaller_StreamingOutputCallResponse = Marshallers.Create((arg) => arg.ToByteArray(), global::grpc.testing.StreamingOutputCallResponse.ParseFrom);
-    static readonly Marshaller<global::grpc.testing.StreamingInputCallRequest> __Marshaller_StreamingInputCallRequest = Marshallers.Create((arg) => arg.ToByteArray(), global::grpc.testing.StreamingInputCallRequest.ParseFrom);
-    static readonly Marshaller<global::grpc.testing.StreamingInputCallResponse> __Marshaller_StreamingInputCallResponse = Marshallers.Create((arg) => arg.ToByteArray(), global::grpc.testing.StreamingInputCallResponse.ParseFrom);
+    static readonly Marshaller<global::Grpc.Testing.Empty> __Marshaller_Empty = Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Testing.Empty.Parser.ParseFrom);
+    static readonly Marshaller<global::Grpc.Testing.SimpleRequest> __Marshaller_SimpleRequest = Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Testing.SimpleRequest.Parser.ParseFrom);
+    static readonly Marshaller<global::Grpc.Testing.SimpleResponse> __Marshaller_SimpleResponse = Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Testing.SimpleResponse.Parser.ParseFrom);
+    static readonly Marshaller<global::Grpc.Testing.StreamingOutputCallRequest> __Marshaller_StreamingOutputCallRequest = Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Testing.StreamingOutputCallRequest.Parser.ParseFrom);
+    static readonly Marshaller<global::Grpc.Testing.StreamingOutputCallResponse> __Marshaller_StreamingOutputCallResponse = Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Testing.StreamingOutputCallResponse.Parser.ParseFrom);
+    static readonly Marshaller<global::Grpc.Testing.StreamingInputCallRequest> __Marshaller_StreamingInputCallRequest = Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Testing.StreamingInputCallRequest.Parser.ParseFrom);
+    static readonly Marshaller<global::Grpc.Testing.StreamingInputCallResponse> __Marshaller_StreamingInputCallResponse = Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Testing.StreamingInputCallResponse.Parser.ParseFrom);
 
-    static readonly Method<global::grpc.testing.Empty, global::grpc.testing.Empty> __Method_EmptyCall = new Method<global::grpc.testing.Empty, global::grpc.testing.Empty>(
+    static readonly Method<global::Grpc.Testing.Empty, global::Grpc.Testing.Empty> __Method_EmptyCall = new Method<global::Grpc.Testing.Empty, global::Grpc.Testing.Empty>(
         MethodType.Unary,
         __ServiceName,
         "EmptyCall",
         __Marshaller_Empty,
         __Marshaller_Empty);
 
-    static readonly Method<global::grpc.testing.SimpleRequest, global::grpc.testing.SimpleResponse> __Method_UnaryCall = new Method<global::grpc.testing.SimpleRequest, global::grpc.testing.SimpleResponse>(
+    static readonly Method<global::Grpc.Testing.SimpleRequest, global::Grpc.Testing.SimpleResponse> __Method_UnaryCall = new Method<global::Grpc.Testing.SimpleRequest, global::Grpc.Testing.SimpleResponse>(
         MethodType.Unary,
         __ServiceName,
         "UnaryCall",
         __Marshaller_SimpleRequest,
         __Marshaller_SimpleResponse);
 
-    static readonly Method<global::grpc.testing.StreamingOutputCallRequest, global::grpc.testing.StreamingOutputCallResponse> __Method_StreamingOutputCall = new Method<global::grpc.testing.StreamingOutputCallRequest, global::grpc.testing.StreamingOutputCallResponse>(
+    static readonly Method<global::Grpc.Testing.StreamingOutputCallRequest, global::Grpc.Testing.StreamingOutputCallResponse> __Method_StreamingOutputCall = new Method<global::Grpc.Testing.StreamingOutputCallRequest, global::Grpc.Testing.StreamingOutputCallResponse>(
         MethodType.ServerStreaming,
         __ServiceName,
         "StreamingOutputCall",
         __Marshaller_StreamingOutputCallRequest,
         __Marshaller_StreamingOutputCallResponse);
 
-    static readonly Method<global::grpc.testing.StreamingInputCallRequest, global::grpc.testing.StreamingInputCallResponse> __Method_StreamingInputCall = new Method<global::grpc.testing.StreamingInputCallRequest, global::grpc.testing.StreamingInputCallResponse>(
+    static readonly Method<global::Grpc.Testing.StreamingInputCallRequest, global::Grpc.Testing.StreamingInputCallResponse> __Method_StreamingInputCall = new Method<global::Grpc.Testing.StreamingInputCallRequest, global::Grpc.Testing.StreamingInputCallResponse>(
         MethodType.ClientStreaming,
         __ServiceName,
         "StreamingInputCall",
         __Marshaller_StreamingInputCallRequest,
         __Marshaller_StreamingInputCallResponse);
 
-    static readonly Method<global::grpc.testing.StreamingOutputCallRequest, global::grpc.testing.StreamingOutputCallResponse> __Method_FullDuplexCall = new Method<global::grpc.testing.StreamingOutputCallRequest, global::grpc.testing.StreamingOutputCallResponse>(
+    static readonly Method<global::Grpc.Testing.StreamingOutputCallRequest, global::Grpc.Testing.StreamingOutputCallResponse> __Method_FullDuplexCall = new Method<global::Grpc.Testing.StreamingOutputCallRequest, global::Grpc.Testing.StreamingOutputCallResponse>(
         MethodType.DuplexStreaming,
         __ServiceName,
         "FullDuplexCall",
         __Marshaller_StreamingOutputCallRequest,
         __Marshaller_StreamingOutputCallResponse);
 
-    static readonly Method<global::grpc.testing.StreamingOutputCallRequest, global::grpc.testing.StreamingOutputCallResponse> __Method_HalfDuplexCall = new Method<global::grpc.testing.StreamingOutputCallRequest, global::grpc.testing.StreamingOutputCallResponse>(
+    static readonly Method<global::Grpc.Testing.StreamingOutputCallRequest, global::Grpc.Testing.StreamingOutputCallResponse> __Method_HalfDuplexCall = new Method<global::Grpc.Testing.StreamingOutputCallRequest, global::Grpc.Testing.StreamingOutputCallResponse>(
         MethodType.DuplexStreaming,
         __ServiceName,
         "HalfDuplexCall",
         __Marshaller_StreamingOutputCallRequest,
         __Marshaller_StreamingOutputCallResponse);
 
+    // service descriptor
+    public static global::Google.Protobuf.Reflection.ServiceDescriptor Descriptor
+    {
+      get { return global::Grpc.Testing.Test.Descriptor.Services[0]; }
+    }
+
     // client interface
     public interface ITestServiceClient
     {
-      global::grpc.testing.Empty EmptyCall(global::grpc.testing.Empty request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
-      global::grpc.testing.Empty EmptyCall(global::grpc.testing.Empty request, CallOptions options);
-      AsyncUnaryCall<global::grpc.testing.Empty> EmptyCallAsync(global::grpc.testing.Empty request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
-      AsyncUnaryCall<global::grpc.testing.Empty> EmptyCallAsync(global::grpc.testing.Empty request, CallOptions options);
-      global::grpc.testing.SimpleResponse UnaryCall(global::grpc.testing.SimpleRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
-      global::grpc.testing.SimpleResponse UnaryCall(global::grpc.testing.SimpleRequest request, CallOptions options);
-      AsyncUnaryCall<global::grpc.testing.SimpleResponse> UnaryCallAsync(global::grpc.testing.SimpleRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
-      AsyncUnaryCall<global::grpc.testing.SimpleResponse> UnaryCallAsync(global::grpc.testing.SimpleRequest request, CallOptions options);
-      AsyncServerStreamingCall<global::grpc.testing.StreamingOutputCallResponse> StreamingOutputCall(global::grpc.testing.StreamingOutputCallRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
-      AsyncServerStreamingCall<global::grpc.testing.StreamingOutputCallResponse> StreamingOutputCall(global::grpc.testing.StreamingOutputCallRequest request, CallOptions options);
-      AsyncClientStreamingCall<global::grpc.testing.StreamingInputCallRequest, global::grpc.testing.StreamingInputCallResponse> StreamingInputCall(Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
-      AsyncClientStreamingCall<global::grpc.testing.StreamingInputCallRequest, global::grpc.testing.StreamingInputCallResponse> StreamingInputCall(CallOptions options);
-      AsyncDuplexStreamingCall<global::grpc.testing.StreamingOutputCallRequest, global::grpc.testing.StreamingOutputCallResponse> FullDuplexCall(Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
-      AsyncDuplexStreamingCall<global::grpc.testing.StreamingOutputCallRequest, global::grpc.testing.StreamingOutputCallResponse> FullDuplexCall(CallOptions options);
-      AsyncDuplexStreamingCall<global::grpc.testing.StreamingOutputCallRequest, global::grpc.testing.StreamingOutputCallResponse> HalfDuplexCall(Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
-      AsyncDuplexStreamingCall<global::grpc.testing.StreamingOutputCallRequest, global::grpc.testing.StreamingOutputCallResponse> HalfDuplexCall(CallOptions options);
+      global::Grpc.Testing.Empty EmptyCall(global::Grpc.Testing.Empty request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
+      global::Grpc.Testing.Empty EmptyCall(global::Grpc.Testing.Empty request, CallOptions options);
+      AsyncUnaryCall<global::Grpc.Testing.Empty> EmptyCallAsync(global::Grpc.Testing.Empty request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
+      AsyncUnaryCall<global::Grpc.Testing.Empty> EmptyCallAsync(global::Grpc.Testing.Empty request, CallOptions options);
+      global::Grpc.Testing.SimpleResponse UnaryCall(global::Grpc.Testing.SimpleRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
+      global::Grpc.Testing.SimpleResponse UnaryCall(global::Grpc.Testing.SimpleRequest request, CallOptions options);
+      AsyncUnaryCall<global::Grpc.Testing.SimpleResponse> UnaryCallAsync(global::Grpc.Testing.SimpleRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
+      AsyncUnaryCall<global::Grpc.Testing.SimpleResponse> UnaryCallAsync(global::Grpc.Testing.SimpleRequest request, CallOptions options);
+      AsyncServerStreamingCall<global::Grpc.Testing.StreamingOutputCallResponse> StreamingOutputCall(global::Grpc.Testing.StreamingOutputCallRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
+      AsyncServerStreamingCall<global::Grpc.Testing.StreamingOutputCallResponse> StreamingOutputCall(global::Grpc.Testing.StreamingOutputCallRequest request, CallOptions options);
+      AsyncClientStreamingCall<global::Grpc.Testing.StreamingInputCallRequest, global::Grpc.Testing.StreamingInputCallResponse> StreamingInputCall(Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
+      AsyncClientStreamingCall<global::Grpc.Testing.StreamingInputCallRequest, global::Grpc.Testing.StreamingInputCallResponse> StreamingInputCall(CallOptions options);
+      AsyncDuplexStreamingCall<global::Grpc.Testing.StreamingOutputCallRequest, global::Grpc.Testing.StreamingOutputCallResponse> FullDuplexCall(Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
+      AsyncDuplexStreamingCall<global::Grpc.Testing.StreamingOutputCallRequest, global::Grpc.Testing.StreamingOutputCallResponse> FullDuplexCall(CallOptions options);
+      AsyncDuplexStreamingCall<global::Grpc.Testing.StreamingOutputCallRequest, global::Grpc.Testing.StreamingOutputCallResponse> HalfDuplexCall(Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
+      AsyncDuplexStreamingCall<global::Grpc.Testing.StreamingOutputCallRequest, global::Grpc.Testing.StreamingOutputCallResponse> HalfDuplexCall(CallOptions options);
     }
 
     // server-side interface
     public interface ITestService
     {
-      Task<global::grpc.testing.Empty> EmptyCall(global::grpc.testing.Empty request, ServerCallContext context);
-      Task<global::grpc.testing.SimpleResponse> UnaryCall(global::grpc.testing.SimpleRequest request, ServerCallContext context);
-      Task StreamingOutputCall(global::grpc.testing.StreamingOutputCallRequest request, IServerStreamWriter<global::grpc.testing.StreamingOutputCallResponse> responseStream, ServerCallContext context);
-      Task<global::grpc.testing.StreamingInputCallResponse> StreamingInputCall(IAsyncStreamReader<global::grpc.testing.StreamingInputCallRequest> requestStream, ServerCallContext context);
-      Task FullDuplexCall(IAsyncStreamReader<global::grpc.testing.StreamingOutputCallRequest> requestStream, IServerStreamWriter<global::grpc.testing.StreamingOutputCallResponse> responseStream, ServerCallContext context);
-      Task HalfDuplexCall(IAsyncStreamReader<global::grpc.testing.StreamingOutputCallRequest> requestStream, IServerStreamWriter<global::grpc.testing.StreamingOutputCallResponse> responseStream, ServerCallContext context);
+      Task<global::Grpc.Testing.Empty> EmptyCall(global::Grpc.Testing.Empty request, ServerCallContext context);
+      Task<global::Grpc.Testing.SimpleResponse> UnaryCall(global::Grpc.Testing.SimpleRequest request, ServerCallContext context);
+      Task StreamingOutputCall(global::Grpc.Testing.StreamingOutputCallRequest request, IServerStreamWriter<global::Grpc.Testing.StreamingOutputCallResponse> responseStream, ServerCallContext context);
+      Task<global::Grpc.Testing.StreamingInputCallResponse> StreamingInputCall(IAsyncStreamReader<global::Grpc.Testing.StreamingInputCallRequest> requestStream, ServerCallContext context);
+      Task FullDuplexCall(IAsyncStreamReader<global::Grpc.Testing.StreamingOutputCallRequest> requestStream, IServerStreamWriter<global::Grpc.Testing.StreamingOutputCallResponse> responseStream, ServerCallContext context);
+      Task HalfDuplexCall(IAsyncStreamReader<global::Grpc.Testing.StreamingOutputCallRequest> requestStream, IServerStreamWriter<global::Grpc.Testing.StreamingOutputCallResponse> responseStream, ServerCallContext context);
     }
 
     // client stub
@@ -100,82 +106,82 @@
       public TestServiceClient(Channel channel) : base(channel)
       {
       }
-      public global::grpc.testing.Empty EmptyCall(global::grpc.testing.Empty request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+      public global::Grpc.Testing.Empty EmptyCall(global::Grpc.Testing.Empty request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
         var call = CreateCall(__Method_EmptyCall, new CallOptions(headers, deadline, cancellationToken));
         return Calls.BlockingUnaryCall(call, request);
       }
-      public global::grpc.testing.Empty EmptyCall(global::grpc.testing.Empty request, CallOptions options)
+      public global::Grpc.Testing.Empty EmptyCall(global::Grpc.Testing.Empty request, CallOptions options)
       {
         var call = CreateCall(__Method_EmptyCall, options);
         return Calls.BlockingUnaryCall(call, request);
       }
-      public AsyncUnaryCall<global::grpc.testing.Empty> EmptyCallAsync(global::grpc.testing.Empty request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+      public AsyncUnaryCall<global::Grpc.Testing.Empty> EmptyCallAsync(global::Grpc.Testing.Empty request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
         var call = CreateCall(__Method_EmptyCall, new CallOptions(headers, deadline, cancellationToken));
         return Calls.AsyncUnaryCall(call, request);
       }
-      public AsyncUnaryCall<global::grpc.testing.Empty> EmptyCallAsync(global::grpc.testing.Empty request, CallOptions options)
+      public AsyncUnaryCall<global::Grpc.Testing.Empty> EmptyCallAsync(global::Grpc.Testing.Empty request, CallOptions options)
       {
         var call = CreateCall(__Method_EmptyCall, options);
         return Calls.AsyncUnaryCall(call, request);
       }
-      public global::grpc.testing.SimpleResponse UnaryCall(global::grpc.testing.SimpleRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+      public global::Grpc.Testing.SimpleResponse UnaryCall(global::Grpc.Testing.SimpleRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
         var call = CreateCall(__Method_UnaryCall, new CallOptions(headers, deadline, cancellationToken));
         return Calls.BlockingUnaryCall(call, request);
       }
-      public global::grpc.testing.SimpleResponse UnaryCall(global::grpc.testing.SimpleRequest request, CallOptions options)
+      public global::Grpc.Testing.SimpleResponse UnaryCall(global::Grpc.Testing.SimpleRequest request, CallOptions options)
       {
         var call = CreateCall(__Method_UnaryCall, options);
         return Calls.BlockingUnaryCall(call, request);
       }
-      public AsyncUnaryCall<global::grpc.testing.SimpleResponse> UnaryCallAsync(global::grpc.testing.SimpleRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+      public AsyncUnaryCall<global::Grpc.Testing.SimpleResponse> UnaryCallAsync(global::Grpc.Testing.SimpleRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
         var call = CreateCall(__Method_UnaryCall, new CallOptions(headers, deadline, cancellationToken));
         return Calls.AsyncUnaryCall(call, request);
       }
-      public AsyncUnaryCall<global::grpc.testing.SimpleResponse> UnaryCallAsync(global::grpc.testing.SimpleRequest request, CallOptions options)
+      public AsyncUnaryCall<global::Grpc.Testing.SimpleResponse> UnaryCallAsync(global::Grpc.Testing.SimpleRequest request, CallOptions options)
       {
         var call = CreateCall(__Method_UnaryCall, options);
         return Calls.AsyncUnaryCall(call, request);
       }
-      public AsyncServerStreamingCall<global::grpc.testing.StreamingOutputCallResponse> StreamingOutputCall(global::grpc.testing.StreamingOutputCallRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+      public AsyncServerStreamingCall<global::Grpc.Testing.StreamingOutputCallResponse> StreamingOutputCall(global::Grpc.Testing.StreamingOutputCallRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
         var call = CreateCall(__Method_StreamingOutputCall, new CallOptions(headers, deadline, cancellationToken));
         return Calls.AsyncServerStreamingCall(call, request);
       }
-      public AsyncServerStreamingCall<global::grpc.testing.StreamingOutputCallResponse> StreamingOutputCall(global::grpc.testing.StreamingOutputCallRequest request, CallOptions options)
+      public AsyncServerStreamingCall<global::Grpc.Testing.StreamingOutputCallResponse> StreamingOutputCall(global::Grpc.Testing.StreamingOutputCallRequest request, CallOptions options)
       {
         var call = CreateCall(__Method_StreamingOutputCall, options);
         return Calls.AsyncServerStreamingCall(call, request);
       }
-      public AsyncClientStreamingCall<global::grpc.testing.StreamingInputCallRequest, global::grpc.testing.StreamingInputCallResponse> StreamingInputCall(Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+      public AsyncClientStreamingCall<global::Grpc.Testing.StreamingInputCallRequest, global::Grpc.Testing.StreamingInputCallResponse> StreamingInputCall(Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
         var call = CreateCall(__Method_StreamingInputCall, new CallOptions(headers, deadline, cancellationToken));
         return Calls.AsyncClientStreamingCall(call);
       }
-      public AsyncClientStreamingCall<global::grpc.testing.StreamingInputCallRequest, global::grpc.testing.StreamingInputCallResponse> StreamingInputCall(CallOptions options)
+      public AsyncClientStreamingCall<global::Grpc.Testing.StreamingInputCallRequest, global::Grpc.Testing.StreamingInputCallResponse> StreamingInputCall(CallOptions options)
       {
         var call = CreateCall(__Method_StreamingInputCall, options);
         return Calls.AsyncClientStreamingCall(call);
       }
-      public AsyncDuplexStreamingCall<global::grpc.testing.StreamingOutputCallRequest, global::grpc.testing.StreamingOutputCallResponse> FullDuplexCall(Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+      public AsyncDuplexStreamingCall<global::Grpc.Testing.StreamingOutputCallRequest, global::Grpc.Testing.StreamingOutputCallResponse> FullDuplexCall(Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
         var call = CreateCall(__Method_FullDuplexCall, new CallOptions(headers, deadline, cancellationToken));
         return Calls.AsyncDuplexStreamingCall(call);
       }
-      public AsyncDuplexStreamingCall<global::grpc.testing.StreamingOutputCallRequest, global::grpc.testing.StreamingOutputCallResponse> FullDuplexCall(CallOptions options)
+      public AsyncDuplexStreamingCall<global::Grpc.Testing.StreamingOutputCallRequest, global::Grpc.Testing.StreamingOutputCallResponse> FullDuplexCall(CallOptions options)
       {
         var call = CreateCall(__Method_FullDuplexCall, options);
         return Calls.AsyncDuplexStreamingCall(call);
       }
-      public AsyncDuplexStreamingCall<global::grpc.testing.StreamingOutputCallRequest, global::grpc.testing.StreamingOutputCallResponse> HalfDuplexCall(Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+      public AsyncDuplexStreamingCall<global::Grpc.Testing.StreamingOutputCallRequest, global::Grpc.Testing.StreamingOutputCallResponse> HalfDuplexCall(Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
         var call = CreateCall(__Method_HalfDuplexCall, new CallOptions(headers, deadline, cancellationToken));
         return Calls.AsyncDuplexStreamingCall(call);
       }
-      public AsyncDuplexStreamingCall<global::grpc.testing.StreamingOutputCallRequest, global::grpc.testing.StreamingOutputCallResponse> HalfDuplexCall(CallOptions options)
+      public AsyncDuplexStreamingCall<global::Grpc.Testing.StreamingOutputCallRequest, global::Grpc.Testing.StreamingOutputCallResponse> HalfDuplexCall(CallOptions options)
       {
         var call = CreateCall(__Method_HalfDuplexCall, options);
         return Calls.AsyncDuplexStreamingCall(call);
diff --git a/src/csharp/Grpc.IntegrationTesting/TestServiceImpl.cs b/src/csharp/Grpc.IntegrationTesting/TestServiceImpl.cs
index ceebd5d..c5bfcf0 100644
--- a/src/csharp/Grpc.IntegrationTesting/TestServiceImpl.cs
+++ b/src/csharp/Grpc.IntegrationTesting/TestServiceImpl.cs
@@ -35,11 +35,11 @@
 using System.Collections.Generic;
 using System.Threading;
 using System.Threading.Tasks;
-using Google.ProtocolBuffers;
+using Google.Protobuf;
 using Grpc.Core;
 using Grpc.Core.Utils;
 
-namespace grpc.testing
+namespace Grpc.Testing
 {
     /// <summary>
     /// Implementation of TestService server
@@ -48,22 +48,20 @@
     {
         public Task<Empty> EmptyCall(Empty request, ServerCallContext context)
         {
-            return Task.FromResult(Empty.DefaultInstance);
+            return Task.FromResult(new Empty());
         }
 
         public Task<SimpleResponse> UnaryCall(SimpleRequest request, ServerCallContext context)
         {
-            var response = SimpleResponse.CreateBuilder()
-                .SetPayload(CreateZerosPayload(request.ResponseSize)).Build();
+            var response = new SimpleResponse { Payload = CreateZerosPayload(request.ResponseSize) };
             return Task.FromResult(response);
         }
 
         public async Task StreamingOutputCall(StreamingOutputCallRequest request, IServerStreamWriter<StreamingOutputCallResponse> responseStream, ServerCallContext context)
         {
-            foreach (var responseParam in request.ResponseParametersList)
+            foreach (var responseParam in request.ResponseParameters)
             {
-                var response = StreamingOutputCallResponse.CreateBuilder()
-                    .SetPayload(CreateZerosPayload(responseParam.Size)).Build();
+                var response = new StreamingOutputCallResponse { Payload = CreateZerosPayload(responseParam.Size) };
                 await responseStream.WriteAsync(response);
             }
         }
@@ -75,17 +73,16 @@
             {
                 sum += request.Payload.Body.Length;
             });
-            return StreamingInputCallResponse.CreateBuilder().SetAggregatedPayloadSize(sum).Build();
+            return new StreamingInputCallResponse { AggregatedPayloadSize = sum };
         }
 
         public async Task FullDuplexCall(IAsyncStreamReader<StreamingOutputCallRequest> requestStream, IServerStreamWriter<StreamingOutputCallResponse> responseStream, ServerCallContext context)
         {
             await requestStream.ForEachAsync(async request =>
             {
-                foreach (var responseParam in request.ResponseParametersList)
+                foreach (var responseParam in request.ResponseParameters)
                 {
-                    var response = StreamingOutputCallResponse.CreateBuilder()
-                        .SetPayload(CreateZerosPayload(responseParam.Size)).Build();
+                    var response = new StreamingOutputCallResponse { Payload = CreateZerosPayload(responseParam.Size) };
                     await responseStream.WriteAsync(response);
                 }
             });
@@ -98,7 +95,7 @@
 
         private static Payload CreateZerosPayload(int size)
         {
-            return Payload.CreateBuilder().SetBody(ByteString.CopyFrom(new byte[size])).Build();
+            return new Payload { Body = ByteString.CopyFrom(new byte[size]) };
         }
     }
 }
diff --git a/src/csharp/Grpc.IntegrationTesting/packages.config b/src/csharp/Grpc.IntegrationTesting/packages.config
index 0867b09..8dfded1 100644
--- a/src/csharp/Grpc.IntegrationTesting/packages.config
+++ b/src/csharp/Grpc.IntegrationTesting/packages.config
@@ -3,6 +3,7 @@
   <package id="BouncyCastle" version="1.7.0" targetFramework="net45" />
   <package id="Google.Apis.Auth" version="1.9.3" targetFramework="net45" />
   <package id="Google.Apis.Core" version="1.9.3" targetFramework="net45" />
+  <package id="Google.Protobuf" version="3.0.0-alpha4" targetFramework="net45" />
   <package id="Google.ProtocolBuffers" version="2.4.1.521" targetFramework="net45" />
   <package id="Ix-Async" version="1.2.3" targetFramework="net45" />
   <package id="Microsoft.Bcl" version="1.1.10" targetFramework="net45" />
diff --git a/src/csharp/Grpc.IntegrationTesting/proto/empty.proto b/src/csharp/Grpc.IntegrationTesting/proto/empty.proto
index 4295a0a..6d0eb93 100644
--- a/src/csharp/Grpc.IntegrationTesting/proto/empty.proto
+++ b/src/csharp/Grpc.IntegrationTesting/proto/empty.proto
@@ -28,7 +28,7 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-syntax = "proto2";
+syntax = "proto3";
 
 package grpc.testing;
 
diff --git a/src/csharp/Grpc.IntegrationTesting/proto/messages.proto b/src/csharp/Grpc.IntegrationTesting/proto/messages.proto
index 65a8140..7df85e3 100644
--- a/src/csharp/Grpc.IntegrationTesting/proto/messages.proto
+++ b/src/csharp/Grpc.IntegrationTesting/proto/messages.proto
@@ -30,7 +30,7 @@
 
 // Message definitions to be used by integration test service definitions.
 
-syntax = "proto2";
+syntax = "proto3";
 
 package grpc.testing;
 
@@ -49,46 +49,46 @@
 // A block of data, to simply increase gRPC message size.
 message Payload {
   // The type of data in body.
-  optional PayloadType type = 1;
+  PayloadType type = 1;
   // Primary contents of payload.
-  optional bytes body = 2;
+  bytes body = 2;
 }
 
 // Unary request.
 message SimpleRequest {
   // Desired payload type in the response from the server.
   // If response_type is RANDOM, server randomly chooses one from other formats.
-  optional PayloadType response_type = 1;
+  PayloadType response_type = 1;
 
   // Desired payload size in the response from the server.
   // If response_type is COMPRESSABLE, this denotes the size before compression.
-  optional int32 response_size = 2;
+  int32 response_size = 2;
 
   // Optional input payload sent along with the request.
-  optional Payload payload = 3;
+  Payload payload = 3;
 
   // Whether SimpleResponse should include username.
-  optional bool fill_username = 4;
+  bool fill_username = 4;
 
   // Whether SimpleResponse should include OAuth scope.
-  optional bool fill_oauth_scope = 5;
+  bool fill_oauth_scope = 5;
 }
 
 // Unary response, as configured by the request.
 message SimpleResponse {
   // Payload to increase message size.
-  optional Payload payload = 1;
+  Payload payload = 1;
   // The user the request came from, for verifying authentication was
   // successful when the client expected it.
-  optional string username = 2;
+  string username = 2;
   // OAuth scope.
-  optional string oauth_scope = 3;
+  string oauth_scope = 3;
 }
 
 // Client-streaming request.
 message StreamingInputCallRequest {
   // Optional input payload sent along with the request.
-  optional Payload payload = 1;
+  Payload payload = 1;
 
   // Not expecting any payload from the response.
 }
@@ -96,18 +96,18 @@
 // Client-streaming response.
 message StreamingInputCallResponse {
   // Aggregated size of payloads received from the client.
-  optional int32 aggregated_payload_size = 1;
+  int32 aggregated_payload_size = 1;
 }
 
 // Configuration for a particular response.
 message ResponseParameters {
   // Desired payload sizes in responses from the server.
   // If response_type is COMPRESSABLE, this denotes the size before compression.
-  optional int32 size = 1;
+  int32 size = 1;
 
   // Desired interval between consecutive responses in the response stream in
   // microseconds.
-  optional int32 interval_us = 2;
+  int32 interval_us = 2;
 }
 
 // Server-streaming request.
@@ -116,17 +116,17 @@
   // If response_type is RANDOM, the payload from each response in the stream
   // might be of different types. This is to simulate a mixed type of payload
   // stream.
-  optional PayloadType response_type = 1;
+  PayloadType response_type = 1;
 
   // Configuration for each expected response message.
   repeated ResponseParameters response_parameters = 2;
 
   // Optional input payload sent along with the request.
-  optional Payload payload = 3;
+  Payload payload = 3;
 }
 
 // Server-streaming response, as configured by the request and parameters.
 message StreamingOutputCallResponse {
   // Payload to increase response size.
-  optional Payload payload = 1;
+  Payload payload = 1;
 }
diff --git a/src/csharp/Grpc.IntegrationTesting/proto/test.proto b/src/csharp/Grpc.IntegrationTesting/proto/test.proto
index 927a3a8..f9e0d2a 100644
--- a/src/csharp/Grpc.IntegrationTesting/proto/test.proto
+++ b/src/csharp/Grpc.IntegrationTesting/proto/test.proto
@@ -30,7 +30,7 @@
 
 // An integration test service that covers all the method signature permutations
 // of unary/streaming requests/responses.
-syntax = "proto2";
+syntax = "proto3";
 
 import "empty.proto";
 import "messages.proto";
diff --git a/src/csharp/Grpc.Tools.nuspec b/src/csharp/Grpc.Tools.nuspec
index eabf5dc..48a7b1f 100644
--- a/src/csharp/Grpc.Tools.nuspec
+++ b/src/csharp/Grpc.Tools.nuspec
@@ -4,19 +4,18 @@
     <id>Grpc.Tools</id>
     <title>gRPC C# Tools</title>
     <summary>Tools for C# implementation of gRPC - an RPC library and framework</summary>
-    <description>Precompiled Windows binaries for generating protocol buffer messages and gRPC client/server code</description>
+    <description>Precompiled Windows binary for generating gRPC client/server code</description>
     <version>$version$</version>
     <authors>Google Inc.</authors>
     <owners>grpc-packages</owners>
     <licenseUrl>https://github.com/grpc/grpc/blob/master/LICENSE</licenseUrl>
     <projectUrl>https://github.com/grpc/grpc</projectUrl>
     <requireLicenseAcceptance>false</requireLicenseAcceptance>
-    <releaseNotes>protoc.exe - protocol buffer compiler v3.0.0-alpha-3; grpc_csharp_plugin.exe - gRPC C# protoc plugin version $version$</releaseNotes>
+    <releaseNotes>grpc_csharp_plugin.exe - gRPC C# protoc plugin version $version$</releaseNotes>
     <copyright>Copyright 2015, Google Inc.</copyright>
     <tags>gRPC RPC Protocol HTTP/2</tags>
   </metadata>
   <files>
-    <file src="protoc.exe" target="tools" />
-    <file src="grpc_csharp_plugin.exe" target="tools" />
+    <file src="..\..\vsprojects\Release\grpc_csharp_plugin.exe" target="tools" />
   </files>
 </package>
diff --git a/src/csharp/build_packages.bat b/src/csharp/build_packages.bat
index 8a11d01..255b746 100644
--- a/src/csharp/build_packages.bat
+++ b/src/csharp/build_packages.bat
@@ -1,8 +1,9 @@
 @rem Builds gRPC NuGet packages
 
 @rem Current package versions
-set VERSION=0.6.1
-set CORE_VERSION=0.10.1
+set VERSION=0.7.0
+set CORE_VERSION=0.11.0
+set PROTOBUF_VERSION=3.0.0-alpha4
 
 @rem Adjust the location of nuget.exe
 set NUGET=C:\nuget\nuget.exe
@@ -14,10 +15,12 @@
 
 @call buildall.bat BUILD_SIGNED || goto :error
 
+@call ..\..\vsprojects\build_plugins.bat || goto :error
+
 %NUGET% pack ..\..\vsprojects\nuget_package\grpc.native.csharp_ext.nuspec -Version %CORE_VERSION% || goto :error
 %NUGET% pack Grpc.Auth\Grpc.Auth.nuspec -Symbols -Version %VERSION% || goto :error
 %NUGET% pack Grpc.Core\Grpc.Core.nuspec -Symbols -Version %VERSION% -Properties GrpcNativeCsharpExtVersion=%CORE_VERSION% || goto :error
-%NUGET% pack Grpc.HealthCheck\Grpc.HealthCheck.nuspec -Symbols -Version %VERSION% || goto :error
+%NUGET% pack Grpc.HealthCheck\Grpc.HealthCheck.nuspec -Symbols -Version %VERSION% -Properties ProtobufVersion=%PROTOBUF_VERSION% || goto :error
 %NUGET% pack Grpc.Tools.nuspec -Version %VERSION% || goto :error
 %NUGET% pack Grpc.nuspec -Version %VERSION% || goto :error
 
diff --git a/src/csharp/ext/grpc_csharp_ext.c b/src/csharp/ext/grpc_csharp_ext.c
index 489e219..70c0fbc 100644
--- a/src/csharp/ext/grpc_csharp_ext.c
+++ b/src/csharp/ext/grpc_csharp_ext.c
@@ -837,11 +837,11 @@
   if (key_cert_pair_cert_chain || key_cert_pair_private_key) {
     key_cert_pair.cert_chain = key_cert_pair_cert_chain;
     key_cert_pair.private_key = key_cert_pair_private_key;
-    return grpc_ssl_credentials_create(pem_root_certs, &key_cert_pair);
+    return grpc_ssl_credentials_create(pem_root_certs, &key_cert_pair, NULL);
   } else {
     GPR_ASSERT(!key_cert_pair_cert_chain);
     GPR_ASSERT(!key_cert_pair_private_key);
-    return grpc_ssl_credentials_create(pem_root_certs, NULL);
+    return grpc_ssl_credentials_create(pem_root_certs, NULL, NULL);
   }
 }
 
@@ -852,7 +852,7 @@
 GPR_EXPORT grpc_channel *GPR_CALLTYPE
 grpcsharp_secure_channel_create(grpc_credentials *creds, const char *target,
                                 const grpc_channel_args *args) {
-  return grpc_secure_channel_create(creds, target, args);
+  return grpc_secure_channel_create(creds, target, args, NULL);
 }
 
 GPR_EXPORT grpc_server_credentials *GPR_CALLTYPE
@@ -876,7 +876,7 @@
   }
   creds = grpc_ssl_server_credentials_create(pem_root_certs, key_cert_pairs,
                                              num_key_cert_pairs,
-                                             force_client_auth);
+                                             force_client_auth, NULL);
   gpr_free(key_cert_pairs);
   return creds;
 }
diff --git a/src/csharp/generate_proto_csharp.sh b/src/csharp/generate_proto_csharp.sh
index 7c3ba70..a17f45b 100755
--- a/src/csharp/generate_proto_csharp.sh
+++ b/src/csharp/generate_proto_csharp.sh
@@ -38,11 +38,11 @@
 INTEROP_DIR=Grpc.IntegrationTesting
 HEALTHCHECK_DIR=Grpc.HealthCheck
 
-$PROTOC --plugin=$PLUGIN --grpc_out=$EXAMPLES_DIR \
+$PROTOC --plugin=$PLUGIN --csharp_out=$EXAMPLES_DIR --grpc_out=$EXAMPLES_DIR \
     -I $EXAMPLES_DIR/proto $EXAMPLES_DIR/proto/math.proto
 
-$PROTOC --plugin=$PLUGIN --grpc_out=$INTEROP_DIR \
-    -I $INTEROP_DIR/proto $INTEROP_DIR/proto/test.proto
+$PROTOC --plugin=$PLUGIN --csharp_out=$INTEROP_DIR --grpc_out=$INTEROP_DIR \
+    -I $INTEROP_DIR/proto $INTEROP_DIR/proto/*.proto
 
-$PROTOC --plugin=$PLUGIN --grpc_out=$HEALTHCHECK_DIR \
+$PROTOC --plugin=$PLUGIN --csharp_out=$HEALTHCHECK_DIR --grpc_out=$HEALTHCHECK_DIR \
     -I $HEALTHCHECK_DIR/proto $HEALTHCHECK_DIR/proto/health.proto
diff --git a/src/node/ext/channel.cc b/src/node/ext/channel.cc
index a61c830..9aed96b 100644
--- a/src/node/ext/channel.cc
+++ b/src/node/ext/channel.cc
@@ -161,7 +161,7 @@
                                                      NULL);
     } else {
       wrapped_channel =
-          grpc_secure_channel_create(creds, *host, channel_args_ptr);
+          grpc_secure_channel_create(creds, *host, channel_args_ptr, NULL);
     }
     if (channel_args_ptr != NULL) {
       free(channel_args_ptr->args);
diff --git a/src/node/ext/credentials.cc b/src/node/ext/credentials.cc
index 21d61f1..85a823a 100644
--- a/src/node/ext/credentials.cc
+++ b/src/node/ext/credentials.cc
@@ -156,7 +156,8 @@
         "createSSl's third argument must be a Buffer if provided");
   }
   grpc_credentials *creds = grpc_ssl_credentials_create(
-      root_certs, key_cert_pair.private_key == NULL ? NULL : &key_cert_pair);
+      root_certs, key_cert_pair.private_key == NULL ? NULL : &key_cert_pair,
+      NULL);
   if (creds == NULL) {
     NanReturnNull();
   }
@@ -176,7 +177,7 @@
   Credentials *creds1 = ObjectWrap::Unwrap<Credentials>(args[0]->ToObject());
   Credentials *creds2 = ObjectWrap::Unwrap<Credentials>(args[1]->ToObject());
   grpc_credentials *creds = grpc_composite_credentials_create(
-      creds1->wrapped_credentials, creds2->wrapped_credentials);
+      creds1->wrapped_credentials, creds2->wrapped_credentials, NULL);
   if (creds == NULL) {
     NanReturnNull();
   }
@@ -185,7 +186,7 @@
 
 NAN_METHOD(Credentials::CreateGce) {
   NanScope();
-  grpc_credentials *creds = grpc_compute_engine_credentials_create();
+  grpc_credentials *creds = grpc_compute_engine_credentials_create(NULL);
   if (creds == NULL) {
     NanReturnNull();
   }
@@ -202,8 +203,8 @@
   }
   NanUtf8String auth_token(args[0]);
   NanUtf8String auth_selector(args[1]);
-  grpc_credentials *creds = grpc_iam_credentials_create(*auth_token,
-                                                       *auth_selector);
+  grpc_credentials *creds =
+      grpc_iam_credentials_create(*auth_token, *auth_selector, NULL);
   if (creds == NULL) {
     NanReturnNull();
   }
diff --git a/src/node/ext/server_credentials.cc b/src/node/ext/server_credentials.cc
index 6e17197..b1201eb 100644
--- a/src/node/ext/server_credentials.cc
+++ b/src/node/ext/server_credentials.cc
@@ -178,11 +178,8 @@
     key_cert_pairs[i].cert_chain = ::node::Buffer::Data(
         pair_obj->Get(cert_key));
   }
-  grpc_server_credentials *creds =
-      grpc_ssl_server_credentials_create(root_certs,
-                                         key_cert_pairs,
-                                         key_cert_pair_count,
-                                         force_client_auth);
+  grpc_server_credentials *creds = grpc_ssl_server_credentials_create(
+      root_certs, key_cert_pairs, key_cert_pair_count, force_client_auth, NULL);
   delete key_cert_pairs;
   if (creds == NULL) {
     NanReturnNull();
diff --git a/src/objective-c/GRPCClient/private/GRPCSecureChannel.m b/src/objective-c/GRPCClient/private/GRPCSecureChannel.m
index 0a54804..ce16655 100644
--- a/src/objective-c/GRPCClient/private/GRPCSecureChannel.m
+++ b/src/objective-c/GRPCClient/private/GRPCSecureChannel.m
@@ -49,7 +49,7 @@
     // Passing NULL to grpc_ssl_credentials_create produces behavior we don't want, so return.
     return NULL;
   }
-  return grpc_ssl_credentials_create(contentInASCII.bytes, NULL);
+  return grpc_ssl_credentials_create(contentInASCII.bytes, NULL, NULL);
 }
 
 @implementation GRPCSecureChannel
@@ -101,8 +101,9 @@
 - (instancetype)initWithHost:(NSString *)host
                  credentials:(grpc_credentials *)credentials
                         args:(grpc_channel_args *)args {
-  return (self =
-          [super initWithChannel:grpc_secure_channel_create(credentials, host.UTF8String, args)]);
+  return (self = [super
+              initWithChannel:grpc_secure_channel_create(
+                                  credentials, host.UTF8String, args, NULL)]);
 }
 
 // TODO(jcanizales): GRPCSecureChannel and GRPCUnsecuredChannel are just convenience initializers
diff --git a/src/php/ext/grpc/channel.c b/src/php/ext/grpc/channel.c
index 7a98167..a4313b6 100644
--- a/src/php/ext/grpc/channel.c
+++ b/src/php/ext/grpc/channel.c
@@ -169,7 +169,7 @@
     } else {
       gpr_log(GPR_DEBUG, "Initialized secure channel");
       channel->wrapped =
-          grpc_secure_channel_create(creds->wrapped, target, &args);
+          grpc_secure_channel_create(creds->wrapped, target, &args, NULL);
     }
     efree(args.args);
   }
diff --git a/src/php/ext/grpc/credentials.c b/src/php/ext/grpc/credentials.c
index 01cb94e..0eba660 100644
--- a/src/php/ext/grpc/credentials.c
+++ b/src/php/ext/grpc/credentials.c
@@ -130,7 +130,7 @@
   }
   grpc_credentials *creds = grpc_ssl_credentials_create(
       pem_root_certs,
-      pem_key_cert_pair.private_key == NULL ? NULL : &pem_key_cert_pair);
+      pem_key_cert_pair.private_key == NULL ? NULL : &pem_key_cert_pair, NULL);
   zval *creds_object = grpc_php_wrap_credentials(creds);
   RETURN_DESTROY_ZVAL(creds_object);
 }
@@ -160,7 +160,7 @@
       (wrapped_grpc_credentials *)zend_object_store_get_object(
           cred2_obj TSRMLS_CC);
   grpc_credentials *creds =
-      grpc_composite_credentials_create(cred1->wrapped, cred2->wrapped);
+      grpc_composite_credentials_create(cred1->wrapped, cred2->wrapped, NULL);
   zval *creds_object = grpc_php_wrap_credentials(creds);
   RETURN_DESTROY_ZVAL(creds_object);
 }
@@ -170,7 +170,7 @@
  * @return Credentials The new GCE credentials object
  */
 PHP_METHOD(Credentials, createGce) {
-  grpc_credentials *creds = grpc_compute_engine_credentials_create();
+  grpc_credentials *creds = grpc_compute_engine_credentials_create(NULL);
   zval *creds_object = grpc_php_wrap_credentials(creds);
   RETURN_DESTROY_ZVAL(creds_object);
 }
diff --git a/src/php/ext/grpc/server_credentials.c b/src/php/ext/grpc/server_credentials.c
index e9183c4..7918824 100644
--- a/src/php/ext/grpc/server_credentials.c
+++ b/src/php/ext/grpc/server_credentials.c
@@ -118,7 +118,7 @@
   /* TODO: add a force_client_auth field in ServerCredentials and pass it as
    * the last parameter. */
   grpc_server_credentials *creds = grpc_ssl_server_credentials_create(
-      pem_root_certs, &pem_key_cert_pair, 1, 0);
+      pem_root_certs, &pem_key_cert_pair, 1, 0, NULL);
   zval *creds_object = grpc_php_wrap_server_credentials(creds);
   RETURN_DESTROY_ZVAL(creds_object);
 }
diff --git a/src/python/grpcio/grpc/_adapter/_c/types/channel.c b/src/python/grpcio/grpc/_adapter/_c/types/channel.c
index cf866dd..79d39c4 100644
--- a/src/python/grpcio/grpc/_adapter/_c/types/channel.c
+++ b/src/python/grpcio/grpc/_adapter/_c/types/channel.c
@@ -106,7 +106,8 @@
   }
   self = (Channel *)type->tp_alloc(type, 0);
   if (creds) {
-    self->c_chan = grpc_secure_channel_create(creds->c_creds, target, &c_args);
+    self->c_chan =
+        grpc_secure_channel_create(creds->c_creds, target, &c_args, NULL);
   } else {
     self->c_chan = grpc_insecure_channel_create(target, &c_args, NULL);
   }
diff --git a/src/python/grpcio/grpc/_adapter/_c/types/client_credentials.c b/src/python/grpcio/grpc/_adapter/_c/types/client_credentials.c
index e314c15..36fd207 100644
--- a/src/python/grpcio/grpc/_adapter/_c/types/client_credentials.c
+++ b/src/python/grpcio/grpc/_adapter/_c/types/client_credentials.c
@@ -135,9 +135,10 @@
   if (private_key && cert_chain) {
     key_cert_pair.private_key = private_key;
     key_cert_pair.cert_chain = cert_chain;
-    self->c_creds = grpc_ssl_credentials_create(root_certs, &key_cert_pair);
+    self->c_creds =
+        grpc_ssl_credentials_create(root_certs, &key_cert_pair, NULL);
   } else {
-    self->c_creds = grpc_ssl_credentials_create(root_certs, NULL);
+    self->c_creds = grpc_ssl_credentials_create(root_certs, NULL, NULL);
   }
   if (!self->c_creds) {
     Py_DECREF(self);
@@ -159,8 +160,8 @@
     return NULL;
   }
   self = (ClientCredentials *)type->tp_alloc(type, 0);
-  self->c_creds = grpc_composite_credentials_create(
-      creds1->c_creds, creds2->c_creds);
+  self->c_creds =
+      grpc_composite_credentials_create(creds1->c_creds, creds2->c_creds, NULL);
   if (!self->c_creds) {
     Py_DECREF(self);
     PyErr_SetString(PyExc_RuntimeError, "couldn't create composite credentials");
@@ -172,7 +173,7 @@
 ClientCredentials *pygrpc_ClientCredentials_compute_engine(
     PyTypeObject *type, PyObject *ignored) {
   ClientCredentials *self = (ClientCredentials *)type->tp_alloc(type, 0);
-  self->c_creds = grpc_compute_engine_credentials_create();
+  self->c_creds = grpc_compute_engine_credentials_create(NULL);
   if (!self->c_creds) {
     Py_DECREF(self);
     PyErr_SetString(PyExc_RuntimeError,
@@ -195,7 +196,7 @@
   }
   self = (ClientCredentials *)type->tp_alloc(type, 0);
   self->c_creds = grpc_service_account_credentials_create(
-      json_key, scope, pygrpc_cast_double_to_gpr_timespec(lifetime));
+      json_key, scope, pygrpc_cast_double_to_gpr_timespec(lifetime), NULL);
   if (!self->c_creds) {
     Py_DECREF(self);
     PyErr_SetString(PyExc_RuntimeError,
@@ -218,7 +219,7 @@
   }
   self = (ClientCredentials *)type->tp_alloc(type, 0);
   self->c_creds = grpc_service_account_jwt_access_credentials_create(
-      json_key, pygrpc_cast_double_to_gpr_timespec(lifetime));
+      json_key, pygrpc_cast_double_to_gpr_timespec(lifetime), NULL);
   if (!self->c_creds) {
     Py_DECREF(self);
     PyErr_SetString(PyExc_RuntimeError, "couldn't create JWT credentials");
@@ -237,7 +238,8 @@
     return NULL;
   }
   self = (ClientCredentials *)type->tp_alloc(type, 0);
-  self->c_creds = grpc_refresh_token_credentials_create(json_refresh_token);
+  self->c_creds =
+      grpc_refresh_token_credentials_create(json_refresh_token, NULL);
   if (!self->c_creds) {
     Py_DECREF(self);
     PyErr_SetString(PyExc_RuntimeError,
@@ -259,7 +261,7 @@
   }
   self = (ClientCredentials *)type->tp_alloc(type, 0);
   self->c_creds = grpc_iam_credentials_create(authorization_token,
-                                              authority_selector);
+                                              authority_selector, NULL);
   if (!self->c_creds) {
     Py_DECREF(self);
     PyErr_SetString(PyExc_RuntimeError, "couldn't create IAM credentials");
diff --git a/src/python/grpcio/grpc/_adapter/_c/types/server_credentials.c b/src/python/grpcio/grpc/_adapter/_c/types/server_credentials.c
index f6859b7..2ba855e 100644
--- a/src/python/grpcio/grpc/_adapter/_c/types/server_credentials.c
+++ b/src/python/grpcio/grpc/_adapter/_c/types/server_credentials.c
@@ -131,7 +131,7 @@
   /* TODO: Add a force_client_auth parameter in the python object and pass it
      here as the last arg. */
   self->c_creds = grpc_ssl_server_credentials_create(
-      root_certs, key_cert_pairs, num_key_cert_pairs, 0);
+      root_certs, key_cert_pairs, num_key_cert_pairs, 0, NULL);
   gpr_free(key_cert_pairs);
   return self;
 }
diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxd b/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxd
index d065383..c793774 100644
--- a/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxd
+++ b/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxd
@@ -332,7 +332,7 @@
   grpc_server_credentials *grpc_ssl_server_credentials_create(
       const char *pem_root_certs,
       grpc_ssl_pem_key_cert_pair *pem_key_cert_pairs,
-      size_t num_key_cert_pairs);
+      size_t num_key_cert_pairs)
   void grpc_server_credentials_release(grpc_server_credentials *creds)
 
   int grpc_server_add_secure_http2_port(grpc_server *server, const char *addr,
diff --git a/src/ruby/ext/grpc/rb_channel.c b/src/ruby/ext/grpc/rb_channel.c
index 6491aa4..90afdc3 100644
--- a/src/ruby/ext/grpc/rb_channel.c
+++ b/src/ruby/ext/grpc/rb_channel.c
@@ -150,7 +150,7 @@
     ch = grpc_insecure_channel_create(target_chars, &args, NULL);
   } else {
     creds = grpc_rb_get_wrapped_credentials(credentials);
-    ch = grpc_secure_channel_create(creds, target_chars, &args);
+    ch = grpc_secure_channel_create(creds, target_chars, &args, NULL);
   }
   if (args.args != NULL) {
     xfree(args.args); /* Allocated by grpc_rb_hash_convert_to_channel_args */
diff --git a/src/ruby/ext/grpc/rb_credentials.c b/src/ruby/ext/grpc/rb_credentials.c
index a9dcdbc..ac3804d 100644
--- a/src/ruby/ext/grpc/rb_credentials.c
+++ b/src/ruby/ext/grpc/rb_credentials.c
@@ -154,7 +154,7 @@
     Creates the default credential instances. */
 static VALUE grpc_rb_compute_engine_credentials_create(VALUE cls) {
   grpc_rb_credentials *wrapper = ALLOC(grpc_rb_credentials);
-  wrapper->wrapped = grpc_compute_engine_credentials_create();
+  wrapper->wrapped = grpc_compute_engine_credentials_create(NULL);
   if (wrapper->wrapped == NULL) {
     rb_raise(rb_eRuntimeError,
              "could not create composite engine credentials, not sure why");
@@ -181,8 +181,8 @@
   TypedData_Get_Struct(other, grpc_rb_credentials,
                        &grpc_rb_credentials_data_type, other_wrapper);
   wrapper = ALLOC(grpc_rb_credentials);
-  wrapper->wrapped = grpc_composite_credentials_create(self_wrapper->wrapped,
-                                                       other_wrapper->wrapped);
+  wrapper->wrapped = grpc_composite_credentials_create(
+      self_wrapper->wrapped, other_wrapper->wrapped, NULL);
   if (wrapper->wrapped == NULL) {
     rb_raise(rb_eRuntimeError,
              "could not create composite credentials, not sure why");
@@ -234,12 +234,13 @@
     return Qnil;
   }
   if (pem_private_key == Qnil && pem_cert_chain == Qnil) {
-    creds = grpc_ssl_credentials_create(RSTRING_PTR(pem_root_certs), NULL);
+    creds =
+        grpc_ssl_credentials_create(RSTRING_PTR(pem_root_certs), NULL, NULL);
   } else {
     key_cert_pair.private_key = RSTRING_PTR(pem_private_key);
     key_cert_pair.cert_chain = RSTRING_PTR(pem_cert_chain);
     creds = grpc_ssl_credentials_create(RSTRING_PTR(pem_root_certs),
-                                        &key_cert_pair);
+                                        &key_cert_pair, NULL);
   }
   if (creds == NULL) {
     rb_raise(rb_eRuntimeError, "could not create a credentials, not sure why");
diff --git a/src/ruby/ext/grpc/rb_server_credentials.c b/src/ruby/ext/grpc/rb_server_credentials.c
index 62c211d..6af4c86 100644
--- a/src/ruby/ext/grpc/rb_server_credentials.c
+++ b/src/ruby/ext/grpc/rb_server_credentials.c
@@ -178,10 +178,11 @@
   key_cert_pair.cert_chain = RSTRING_PTR(pem_cert_chain);
   /* TODO Add a force_client_auth parameter and pass it here. */
   if (pem_root_certs == Qnil) {
-    creds = grpc_ssl_server_credentials_create(NULL, &key_cert_pair, 1, 0);
+    creds =
+        grpc_ssl_server_credentials_create(NULL, &key_cert_pair, 1, 0, NULL);
   } else {
     creds = grpc_ssl_server_credentials_create(RSTRING_PTR(pem_root_certs),
-                                               &key_cert_pair, 1, 0);
+                                               &key_cert_pair, 1, 0, NULL);
   }
   if (creds == NULL) {
     rb_raise(rb_eRuntimeError, "could not create a credentials, not sure why");
diff --git a/templates/vsprojects/vcxproj_defs.include b/templates/vsprojects/vcxproj_defs.include
index 507c9a5..b1ed898 100644
--- a/templates/vsprojects/vcxproj_defs.include
+++ b/templates/vsprojects/vcxproj_defs.include
@@ -23,7 +23,7 @@
     props.extend(['cpptest'])
   if configuration_type == 'Application':
     if target.build == 'protoc':
-      props.extend(['protoc'])
+      props.extend(['protoc', 'protobuf'])
     else:
       props.extend(['winsock', 'protobuf', 'zlib', 'openssl'])
   else:
diff --git a/test/core/end2end/fixtures/chttp2_fake_security.c b/test/core/end2end/fixtures/chttp2_fake_security.c
index a0a6793..b4a248f 100644
--- a/test/core/end2end/fixtures/chttp2_fake_security.c
+++ b/test/core/end2end/fixtures/chttp2_fake_security.c
@@ -77,7 +77,8 @@
                                                 grpc_channel_args *client_args,
                                                 grpc_credentials *creds) {
   fullstack_secure_fixture_data *ffd = f->fixture_data;
-  f->client = grpc_secure_channel_create(creds, ffd->localaddr, client_args);
+  f->client =
+      grpc_secure_channel_create(creds, ffd->localaddr, client_args, NULL);
   GPR_ASSERT(f->client != NULL);
   grpc_credentials_release(creds);
 }
diff --git a/test/core/end2end/fixtures/chttp2_simple_ssl_fullstack.c b/test/core/end2end/fixtures/chttp2_simple_ssl_fullstack.c
index beae241..201d202 100644
--- a/test/core/end2end/fixtures/chttp2_simple_ssl_fullstack.c
+++ b/test/core/end2end/fixtures/chttp2_simple_ssl_fullstack.c
@@ -80,7 +80,8 @@
                                                 grpc_channel_args *client_args,
                                                 grpc_credentials *creds) {
   fullstack_secure_fixture_data *ffd = f->fixture_data;
-  f->client = grpc_secure_channel_create(creds, ffd->localaddr, client_args);
+  f->client =
+      grpc_secure_channel_create(creds, ffd->localaddr, client_args, NULL);
   GPR_ASSERT(f->client != NULL);
   grpc_credentials_release(creds);
 }
@@ -108,7 +109,7 @@
 
 static void chttp2_init_client_simple_ssl_secure_fullstack(
     grpc_end2end_test_fixture *f, grpc_channel_args *client_args) {
-  grpc_credentials *ssl_creds = grpc_ssl_credentials_create(NULL, NULL);
+  grpc_credentials *ssl_creds = grpc_ssl_credentials_create(NULL, NULL, NULL);
   grpc_arg ssl_name_override = {GRPC_ARG_STRING,
                                 GRPC_SSL_TARGET_NAME_OVERRIDE_ARG,
                                 {"foo.test.google.fr"}};
@@ -135,7 +136,7 @@
   grpc_ssl_pem_key_cert_pair pem_cert_key_pair = {test_server1_key,
                                                   test_server1_cert};
   grpc_server_credentials *ssl_creds =
-      grpc_ssl_server_credentials_create(NULL, &pem_cert_key_pair, 1, 0);
+      grpc_ssl_server_credentials_create(NULL, &pem_cert_key_pair, 1, 0, NULL);
   if (fail_server_auth_check(server_args)) {
     grpc_auth_metadata_processor processor = {process_auth_failure, NULL};
     grpc_server_credentials_set_auth_metadata_processor(ssl_creds, processor);
diff --git a/test/core/end2end/fixtures/chttp2_simple_ssl_fullstack_with_poll.c b/test/core/end2end/fixtures/chttp2_simple_ssl_fullstack_with_poll.c
index c8971be..e7375f1 100644
--- a/test/core/end2end/fixtures/chttp2_simple_ssl_fullstack_with_poll.c
+++ b/test/core/end2end/fixtures/chttp2_simple_ssl_fullstack_with_poll.c
@@ -80,7 +80,8 @@
                                                 grpc_channel_args *client_args,
                                                 grpc_credentials *creds) {
   fullstack_secure_fixture_data *ffd = f->fixture_data;
-  f->client = grpc_secure_channel_create(creds, ffd->localaddr, client_args);
+  f->client =
+      grpc_secure_channel_create(creds, ffd->localaddr, client_args, NULL);
   GPR_ASSERT(f->client != NULL);
   grpc_credentials_release(creds);
 }
@@ -108,7 +109,7 @@
 
 static void chttp2_init_client_simple_ssl_secure_fullstack(
     grpc_end2end_test_fixture *f, grpc_channel_args *client_args) {
-  grpc_credentials *ssl_creds = grpc_ssl_credentials_create(NULL, NULL);
+  grpc_credentials *ssl_creds = grpc_ssl_credentials_create(NULL, NULL, NULL);
   grpc_arg ssl_name_override = {GRPC_ARG_STRING,
                                 GRPC_SSL_TARGET_NAME_OVERRIDE_ARG,
                                 {"foo.test.google.fr"}};
@@ -135,7 +136,7 @@
   grpc_ssl_pem_key_cert_pair pem_cert_key_pair = {test_server1_key,
                                                   test_server1_cert};
   grpc_server_credentials *ssl_creds =
-      grpc_ssl_server_credentials_create(NULL, &pem_cert_key_pair, 1, 0);
+      grpc_ssl_server_credentials_create(NULL, &pem_cert_key_pair, 1, 0, NULL);
   if (fail_server_auth_check(server_args)) {
     grpc_auth_metadata_processor processor = {process_auth_failure, NULL};
     grpc_server_credentials_set_auth_metadata_processor(ssl_creds, processor);
diff --git a/test/core/end2end/fixtures/chttp2_simple_ssl_fullstack_with_proxy.c b/test/core/end2end/fixtures/chttp2_simple_ssl_fullstack_with_proxy.c
index a518a7d..be0dda2 100644
--- a/test/core/end2end/fixtures/chttp2_simple_ssl_fullstack_with_proxy.c
+++ b/test/core/end2end/fixtures/chttp2_simple_ssl_fullstack_with_proxy.c
@@ -58,7 +58,7 @@
   grpc_ssl_pem_key_cert_pair pem_cert_key_pair = {test_server1_key,
                                                   test_server1_cert};
   grpc_server_credentials *ssl_creds =
-      grpc_ssl_server_credentials_create(NULL, &pem_cert_key_pair, 1, 0);
+      grpc_ssl_server_credentials_create(NULL, &pem_cert_key_pair, 1, 0, NULL);
   GPR_ASSERT(grpc_server_add_secure_http2_port(s, port, ssl_creds));
   grpc_server_credentials_release(ssl_creds);
   return s;
@@ -66,14 +66,14 @@
 
 static grpc_channel *create_proxy_client(const char *target) {
   grpc_channel *channel;
-  grpc_credentials *ssl_creds = grpc_ssl_credentials_create(NULL, NULL);
+  grpc_credentials *ssl_creds = grpc_ssl_credentials_create(NULL, NULL, NULL);
   grpc_arg ssl_name_override = {GRPC_ARG_STRING,
                                 GRPC_SSL_TARGET_NAME_OVERRIDE_ARG,
                                 {"foo.test.google.fr"}};
   grpc_channel_args client_args;
   client_args.num_args = 1;
   client_args.args = &ssl_name_override;
-  channel = grpc_secure_channel_create(ssl_creds, target, &client_args);
+  channel = grpc_secure_channel_create(ssl_creds, target, &client_args, NULL);
   grpc_credentials_release(ssl_creds);
   return channel;
 }
@@ -109,7 +109,8 @@
                                                 grpc_credentials *creds) {
   fullstack_secure_fixture_data *ffd = f->fixture_data;
   f->client = grpc_secure_channel_create(
-      creds, grpc_end2end_proxy_get_client_target(ffd->proxy), client_args);
+      creds, grpc_end2end_proxy_get_client_target(ffd->proxy), client_args,
+      NULL);
   GPR_ASSERT(f->client != NULL);
   grpc_credentials_release(creds);
 }
@@ -137,7 +138,7 @@
 
 static void chttp2_init_client_simple_ssl_secure_fullstack(
     grpc_end2end_test_fixture *f, grpc_channel_args *client_args) {
-  grpc_credentials *ssl_creds = grpc_ssl_credentials_create(NULL, NULL);
+  grpc_credentials *ssl_creds = grpc_ssl_credentials_create(NULL, NULL, NULL);
   grpc_arg ssl_name_override = {GRPC_ARG_STRING,
                                 GRPC_SSL_TARGET_NAME_OVERRIDE_ARG,
                                 {"foo.test.google.fr"}};
@@ -164,7 +165,7 @@
   grpc_ssl_pem_key_cert_pair pem_cert_key_pair = {test_server1_key,
                                                   test_server1_cert};
   grpc_server_credentials *ssl_creds =
-      grpc_ssl_server_credentials_create(NULL, &pem_cert_key_pair, 1, 0);
+      grpc_ssl_server_credentials_create(NULL, &pem_cert_key_pair, 1, 0, NULL);
   if (fail_server_auth_check(server_args)) {
     grpc_auth_metadata_processor processor = {process_auth_failure, NULL};
     grpc_server_credentials_set_auth_metadata_processor(ssl_creds, processor);
diff --git a/test/core/end2end/fixtures/chttp2_simple_ssl_with_oauth2_fullstack.c b/test/core/end2end/fixtures/chttp2_simple_ssl_with_oauth2_fullstack.c
index 7f11028..9a545b1 100644
--- a/test/core/end2end/fixtures/chttp2_simple_ssl_with_oauth2_fullstack.c
+++ b/test/core/end2end/fixtures/chttp2_simple_ssl_with_oauth2_fullstack.c
@@ -113,7 +113,8 @@
                                                 grpc_channel_args *client_args,
                                                 grpc_credentials *creds) {
   fullstack_secure_fixture_data *ffd = f->fixture_data;
-  f->client = grpc_secure_channel_create(creds, ffd->localaddr, client_args);
+  f->client =
+      grpc_secure_channel_create(creds, ffd->localaddr, client_args, NULL);
   GPR_ASSERT(f->client != NULL);
   grpc_credentials_release(creds);
 }
@@ -142,11 +143,11 @@
 static void chttp2_init_client_simple_ssl_with_oauth2_secure_fullstack(
     grpc_end2end_test_fixture *f, grpc_channel_args *client_args) {
   grpc_credentials *ssl_creds =
-      grpc_ssl_credentials_create(test_root_cert, NULL);
+      grpc_ssl_credentials_create(test_root_cert, NULL, NULL);
   grpc_credentials *oauth2_creds =
       grpc_md_only_test_credentials_create("Authorization", oauth2_md, 1);
   grpc_credentials *ssl_oauth2_creds =
-      grpc_composite_credentials_create(ssl_creds, oauth2_creds);
+      grpc_composite_credentials_create(ssl_creds, oauth2_creds, NULL);
   grpc_arg ssl_name_override = {GRPC_ARG_STRING,
                                 GRPC_SSL_TARGET_NAME_OVERRIDE_ARG,
                                 {"foo.test.google.fr"}};
@@ -175,7 +176,7 @@
   grpc_ssl_pem_key_cert_pair pem_key_cert_pair = {test_server1_key,
                                                   test_server1_cert};
   grpc_server_credentials *ssl_creds =
-      grpc_ssl_server_credentials_create(NULL, &pem_key_cert_pair, 1, 0);
+      grpc_ssl_server_credentials_create(NULL, &pem_key_cert_pair, 1, 0, NULL);
   grpc_auth_metadata_processor processor;
   processor.state = NULL;
   if (fail_server_auth_check(server_args)) {
diff --git a/test/core/end2end/tests/request_response_with_payload_and_call_creds.c b/test/core/end2end/tests/request_response_with_payload_and_call_creds.c
index d862274..48dd0aa 100644
--- a/test/core/end2end/tests/request_response_with_payload_and_call_creds.c
+++ b/test/core/end2end/tests/request_response_with_payload_and_call_creds.c
@@ -190,7 +190,7 @@
   c = grpc_channel_create_call(f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq,
                                "/foo", "foo.test.google.fr", deadline, NULL);
   GPR_ASSERT(c);
-  creds = grpc_iam_credentials_create(iam_token, iam_selector);
+  creds = grpc_iam_credentials_create(iam_token, iam_selector, NULL);
   GPR_ASSERT(creds != NULL);
   GPR_ASSERT(grpc_call_set_credentials(c, creds) == GRPC_CALL_OK);
   switch (mode) {
@@ -199,7 +199,7 @@
     case OVERRIDE:
       grpc_credentials_release(creds);
       creds = grpc_iam_credentials_create(overridden_iam_token,
-                                          overridden_iam_selector);
+                                          overridden_iam_selector, NULL);
       GPR_ASSERT(creds != NULL);
       GPR_ASSERT(grpc_call_set_credentials(c, creds) == GRPC_CALL_OK);
       break;
@@ -421,7 +421,7 @@
                                "/foo", "foo.test.google.fr", deadline, NULL);
   GPR_ASSERT(c);
 
-  creds = grpc_iam_credentials_create(iam_token, iam_selector);
+  creds = grpc_iam_credentials_create(iam_token, iam_selector, NULL);
   GPR_ASSERT(creds != NULL);
   GPR_ASSERT(grpc_call_set_credentials(c, creds) == GRPC_CALL_OK);
   grpc_credentials_release(creds);
diff --git a/test/core/fling/server.c b/test/core/fling/server.c
index 0102179..0430ff9 100644
--- a/test/core/fling/server.c
+++ b/test/core/fling/server.c
@@ -215,8 +215,8 @@
   if (secure) {
     grpc_ssl_pem_key_cert_pair pem_key_cert_pair = {test_server1_key,
                                                     test_server1_cert};
-    grpc_server_credentials *ssl_creds =
-        grpc_ssl_server_credentials_create(NULL, &pem_key_cert_pair, 1, 0);
+    grpc_server_credentials *ssl_creds = grpc_ssl_server_credentials_create(
+        NULL, &pem_key_cert_pair, 1, 0, NULL);
     server = grpc_server_create(NULL, NULL);
     GPR_ASSERT(grpc_server_add_secure_http2_port(server, addr, ssl_creds));
     grpc_server_credentials_release(ssl_creds);
diff --git a/test/core/security/credentials_test.c b/test/core/security/credentials_test.c
index e4a8144..880fc5d 100644
--- a/test/core/security/credentials_test.c
+++ b/test/core/security/credentials_test.c
@@ -329,7 +329,7 @@
 
 static void test_iam_creds(void) {
   grpc_credentials *creds = grpc_iam_credentials_create(
-      test_iam_authorization_token, test_iam_authority_selector);
+      test_iam_authorization_token, test_iam_authority_selector, NULL);
   GPR_ASSERT(grpc_credentials_has_request_metadata(creds));
   GPR_ASSERT(grpc_credentials_has_request_metadata_only(creds));
   grpc_credentials_get_request_metadata(creds, NULL, test_service_url,
@@ -349,7 +349,7 @@
 }
 
 static void test_access_token_creds(void) {
-  grpc_credentials *creds = grpc_access_token_credentials_create("blah");
+  grpc_credentials *creds = grpc_access_token_credentials_create("blah", NULL);
   GPR_ASSERT(grpc_credentials_has_request_metadata(creds));
   GPR_ASSERT(grpc_credentials_has_request_metadata_only(creds));
   GPR_ASSERT(strcmp(creds->type, GRPC_CREDENTIALS_TYPE_OAUTH2) == 0);
@@ -371,12 +371,12 @@
 
 static void test_ssl_oauth2_composite_creds(void) {
   grpc_credentials *ssl_creds =
-      grpc_ssl_credentials_create(test_root_cert, NULL);
+      grpc_ssl_credentials_create(test_root_cert, NULL, NULL);
   const grpc_credentials_array *creds_array;
   grpc_credentials *oauth2_creds = grpc_md_only_test_credentials_create(
       "Authorization", test_oauth2_bearer_token, 0);
   grpc_credentials *composite_creds =
-      grpc_composite_credentials_create(ssl_creds, oauth2_creds);
+      grpc_composite_credentials_create(ssl_creds, oauth2_creds, NULL);
   grpc_credentials_unref(ssl_creds);
   grpc_credentials_unref(oauth2_creds);
   GPR_ASSERT(strcmp(composite_creds->type, GRPC_CREDENTIALS_TYPE_COMPOSITE) ==
@@ -395,13 +395,13 @@
 }
 
 void test_ssl_fake_transport_security_composite_creds_failure(void) {
-  grpc_credentials *ssl_creds = grpc_ssl_credentials_create(NULL, NULL);
+  grpc_credentials *ssl_creds = grpc_ssl_credentials_create(NULL, NULL, NULL);
   grpc_credentials *fake_transport_security_creds =
       grpc_fake_transport_security_credentials_create();
 
   /* 2 connector credentials: should not work. */
   GPR_ASSERT(grpc_composite_credentials_create(
-                 ssl_creds, fake_transport_security_creds) == NULL);
+                 ssl_creds, fake_transport_security_creds, NULL) == NULL);
   grpc_credentials_unref(ssl_creds);
   grpc_credentials_unref(fake_transport_security_creds);
 }
@@ -422,16 +422,16 @@
 
 static void test_ssl_oauth2_iam_composite_creds(void) {
   grpc_credentials *ssl_creds =
-      grpc_ssl_credentials_create(test_root_cert, NULL);
+      grpc_ssl_credentials_create(test_root_cert, NULL, NULL);
   const grpc_credentials_array *creds_array;
   grpc_credentials *oauth2_creds = grpc_md_only_test_credentials_create(
       "Authorization", test_oauth2_bearer_token, 0);
   grpc_credentials *aux_creds =
-      grpc_composite_credentials_create(ssl_creds, oauth2_creds);
+      grpc_composite_credentials_create(ssl_creds, oauth2_creds, NULL);
   grpc_credentials *iam_creds = grpc_iam_credentials_create(
-      test_iam_authorization_token, test_iam_authority_selector);
+      test_iam_authorization_token, test_iam_authority_selector, NULL);
   grpc_credentials *composite_creds =
-      grpc_composite_credentials_create(aux_creds, iam_creds);
+      grpc_composite_credentials_create(aux_creds, iam_creds, NULL);
   grpc_credentials_unref(ssl_creds);
   grpc_credentials_unref(oauth2_creds);
   grpc_credentials_unref(aux_creds);
@@ -524,7 +524,7 @@
 
 static void test_compute_engine_creds_success(void) {
   grpc_credentials *compute_engine_creds =
-      grpc_compute_engine_credentials_create();
+      grpc_compute_engine_credentials_create(NULL);
   GPR_ASSERT(grpc_credentials_has_request_metadata(compute_engine_creds));
   GPR_ASSERT(grpc_credentials_has_request_metadata_only(compute_engine_creds));
 
@@ -548,7 +548,7 @@
 
 static void test_compute_engine_creds_failure(void) {
   grpc_credentials *compute_engine_creds =
-      grpc_compute_engine_credentials_create();
+      grpc_compute_engine_credentials_create(NULL);
   grpc_httpcli_set_override(compute_engine_httpcli_get_failure_override,
                             httpcli_post_should_not_be_called);
   GPR_ASSERT(grpc_credentials_has_request_metadata(compute_engine_creds));
@@ -605,7 +605,7 @@
 
 static void test_refresh_token_creds_success(void) {
   grpc_credentials *refresh_token_creds =
-      grpc_refresh_token_credentials_create(test_refresh_token_str);
+      grpc_refresh_token_credentials_create(test_refresh_token_str, NULL);
   GPR_ASSERT(grpc_credentials_has_request_metadata(refresh_token_creds));
   GPR_ASSERT(grpc_credentials_has_request_metadata_only(refresh_token_creds));
 
@@ -629,7 +629,7 @@
 
 static void test_refresh_token_creds_failure(void) {
   grpc_credentials *refresh_token_creds =
-      grpc_refresh_token_credentials_create(test_refresh_token_str);
+      grpc_refresh_token_credentials_create(test_refresh_token_str, NULL);
   grpc_httpcli_set_override(httpcli_get_should_not_be_called,
                             refresh_token_httpcli_post_failure);
   GPR_ASSERT(grpc_credentials_has_request_metadata(refresh_token_creds));
@@ -731,7 +731,7 @@
   char *json_key_string = test_json_key_str();
   grpc_credentials *service_account_creds =
       grpc_service_account_credentials_create(json_key_string, test_scope,
-                                              grpc_max_auth_token_lifetime);
+                                              grpc_max_auth_token_lifetime, NULL);
   GPR_ASSERT(grpc_credentials_has_request_metadata(service_account_creds));
   GPR_ASSERT(grpc_credentials_has_request_metadata_only(service_account_creds));
 
@@ -761,8 +761,8 @@
 static void test_service_account_creds_http_failure(void) {
   char *json_key_string = test_json_key_str();
   grpc_credentials *service_account_creds =
-      grpc_service_account_credentials_create(json_key_string, test_scope,
-                                              grpc_max_auth_token_lifetime);
+      grpc_service_account_credentials_create(
+          json_key_string, test_scope, grpc_max_auth_token_lifetime, NULL);
   GPR_ASSERT(grpc_credentials_has_request_metadata(service_account_creds));
   GPR_ASSERT(grpc_credentials_has_request_metadata_only(service_account_creds));
 
@@ -781,8 +781,8 @@
 static void test_service_account_creds_signing_failure(void) {
   char *json_key_string = test_json_key_str();
   grpc_credentials *service_account_creds =
-      grpc_service_account_credentials_create(json_key_string, test_scope,
-                                              grpc_max_auth_token_lifetime);
+      grpc_service_account_credentials_create(
+          json_key_string, test_scope, grpc_max_auth_token_lifetime, NULL);
   GPR_ASSERT(grpc_credentials_has_request_metadata(service_account_creds));
   GPR_ASSERT(grpc_credentials_has_request_metadata_only(service_account_creds));
 
@@ -828,7 +828,7 @@
   char *json_key_string = test_json_key_str();
   grpc_credentials *jwt_creds =
       grpc_service_account_jwt_access_credentials_create(
-          json_key_string, grpc_max_auth_token_lifetime);
+          json_key_string, grpc_max_auth_token_lifetime, NULL);
   GPR_ASSERT(grpc_credentials_has_request_metadata(jwt_creds));
   GPR_ASSERT(grpc_credentials_has_request_metadata_only(jwt_creds));
 
@@ -861,7 +861,7 @@
   char *json_key_string = test_json_key_str();
   grpc_credentials *jwt_creds =
       grpc_service_account_jwt_access_credentials_create(
-          json_key_string, grpc_max_auth_token_lifetime);
+          json_key_string, grpc_max_auth_token_lifetime, NULL);
   GPR_ASSERT(grpc_credentials_has_request_metadata(jwt_creds));
   GPR_ASSERT(grpc_credentials_has_request_metadata_only(jwt_creds));
 
diff --git a/test/core/security/fetch_oauth2.c b/test/core/security/fetch_oauth2.c
index 64c4dde..7354a9f 100644
--- a/test/core/security/fetch_oauth2.c
+++ b/test/core/security/fetch_oauth2.c
@@ -56,7 +56,7 @@
   }
   return grpc_service_account_credentials_create(
       (const char *)GPR_SLICE_START_PTR(json_key), scope,
-      grpc_max_auth_token_lifetime);
+      grpc_max_auth_token_lifetime, NULL);
 }
 
 static grpc_credentials *create_refresh_token_creds(
@@ -69,7 +69,7 @@
     exit(1);
   }
   return grpc_refresh_token_credentials_create(
-      (const char *)GPR_SLICE_START_PTR(refresh_token));
+      (const char *)GPR_SLICE_START_PTR(refresh_token), NULL);
 }
 
 int main(int argc, char **argv) {
@@ -112,7 +112,7 @@
               "Ignoring json key and scope to get a token from the GCE "
               "metadata server.");
     }
-    creds = grpc_compute_engine_credentials_create();
+    creds = grpc_compute_engine_credentials_create(NULL);
     if (creds == NULL) {
       gpr_log(GPR_ERROR, "Could not create gce credentials.");
       exit(1);
diff --git a/third_party/protobuf b/third_party/protobuf
index 3e2c8a5..2340868 160000
--- a/third_party/protobuf
+++ b/third_party/protobuf
@@ -1 +1 @@
-Subproject commit 3e2c8a5dd79481e1d36572cdf65be93514ba6581
+Subproject commit 23408684b4d2bf1b25e14314413a14d542c18bc4
diff --git a/tools/run_tests/run_sanity.sh b/tools/run_tests/run_sanity.sh
index ac331b5..2737e56 100755
--- a/tools/run_tests/run_sanity.sh
+++ b/tools/run_tests/run_sanity.sh
@@ -46,7 +46,7 @@
  05b155ff59114735ec8cd089f669c4c3d8f59029 third_party/gflags (v2.1.0-45-g05b155f)
  c99458533a9b4c743ed51537e25989ea55944908 third_party/googletest (release-1.7.0)
  33dd08320648ac71d7d9d732be774ed3818dccc5 third_party/openssl (OpenSSL_1_0_2d)
- 3e2c8a5dd79481e1d36572cdf65be93514ba6581 third_party/protobuf (v3.0.0-alpha-1-1048-g3e2c8a5)
+ 23408684b4d2bf1b25e14314413a14d542c18bc4 third_party/protobuf (v3.0.0-alpha-1-1592-g2340868)
  50893291621658f355bc5b4d450a8d06a563053d third_party/zlib (v1.2.8)
 EOF
 
diff --git a/vsprojects/README.md b/vsprojects/README.md
index e6cbf83..b95b468 100644
--- a/vsprojects/README.md
+++ b/vsprojects/README.md
@@ -80,7 +80,12 @@
 For generating service stub code, gRPC relies on plugins for `protoc` (the protocol buffer compiler). The solution `grpc_protoc_plugins.sln` allows you to build
 Windows .exe binaries of gRPC protoc plugins.
 
-1. Open solution `third_party\protobuf\vsprojects\protobuf.sln`
-2. Accept the conversion to newer Visual Studio version and ignore errors about gtest.
-3. Build libprotoc in Release mode.
-4. Open solution `vsprojects\grpc_protoc_plugins.sln` and build it in Release mode. As a result, you should obtain a set of gRPC protoc plugin binaries (`grpc_cpp_plugin.exe`, `grpc_csharp_plugin.exe`, ...)
+1. Follow instructions in `third_party\protobuf\cmake\README.md` to create Visual Studio 2013 projects for protobuf.
+```
+$ cd third_party/protobuf/cmake
+$ cmake -G "Visual Studio 12 2013"
+```
+
+2. Open solution `third_party\protobuf\cmake\protobuf.sln` and build it in Release mode. That will build libraries `libprotobuf.lib` and `libprotoc.lib` needed for the next step.
+
+3. Open solution `vsprojects\grpc_protoc_plugins.sln` and build it in Release mode. As a result, you should obtain a set of gRPC protoc plugin binaries (`grpc_cpp_plugin.exe`, `grpc_csharp_plugin.exe`, ...)
diff --git a/vsprojects/build_plugins.bat b/vsprojects/build_plugins.bat
new file mode 100644
index 0000000..4c33a58
--- /dev/null
+++ b/vsprojects/build_plugins.bat
@@ -0,0 +1,23 @@
+@rem Convenience script to build gRPC protoc plugins from command line. protoc plugins are used to generate service stub code from .proto service defintions.
+
+setlocal
+
+@rem enter this directory
+cd /d %~dp0
+
+@rem Set VS variables (uses Visual Studio 2013)
+@call "%VS120COMNTOOLS%\..\..\vc\vcvarsall.bat" x86
+
+@rem Build third_party/protobuf
+msbuild ..\third_party\protobuf\cmake\protobuf.sln /p:Configuration=Release || goto :error
+
+@rem Build the C# protoc plugins
+msbuild grpc_protoc_plugins.sln /p:Configuration=Release || goto :error
+
+endlocal
+
+goto :EOF
+
+:error
+echo Failed!
+exit /b %errorlevel%
diff --git a/vsprojects/grpc_cpp_plugin/grpc_cpp_plugin.vcxproj b/vsprojects/grpc_cpp_plugin/grpc_cpp_plugin.vcxproj
index 1693a48..1fd03e1 100644
--- a/vsprojects/grpc_cpp_plugin/grpc_cpp_plugin.vcxproj
+++ b/vsprojects/grpc_cpp_plugin/grpc_cpp_plugin.vcxproj
@@ -48,6 +48,7 @@
   <ImportGroup Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
     <Import Project="..\protoc.props" />
+    <Import Project="..\protobuf.props" />
     <Import Project="..\global.props" />
   </ImportGroup>
   <PropertyGroup Label="UserMacros" />
diff --git a/vsprojects/grpc_csharp_plugin/grpc_csharp_plugin.vcxproj b/vsprojects/grpc_csharp_plugin/grpc_csharp_plugin.vcxproj
index aae8272..2d63a84 100644
--- a/vsprojects/grpc_csharp_plugin/grpc_csharp_plugin.vcxproj
+++ b/vsprojects/grpc_csharp_plugin/grpc_csharp_plugin.vcxproj
@@ -48,6 +48,7 @@
   <ImportGroup Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
     <Import Project="..\protoc.props" />
+    <Import Project="..\protobuf.props" />
     <Import Project="..\global.props" />
   </ImportGroup>
   <PropertyGroup Label="UserMacros" />
diff --git a/vsprojects/grpc_objective_c_plugin/grpc_objective_c_plugin.vcxproj b/vsprojects/grpc_objective_c_plugin/grpc_objective_c_plugin.vcxproj
index 07a837a..46e064f 100644
--- a/vsprojects/grpc_objective_c_plugin/grpc_objective_c_plugin.vcxproj
+++ b/vsprojects/grpc_objective_c_plugin/grpc_objective_c_plugin.vcxproj
@@ -48,6 +48,7 @@
   <ImportGroup Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
     <Import Project="..\protoc.props" />
+    <Import Project="..\protobuf.props" />
     <Import Project="..\global.props" />
   </ImportGroup>
   <PropertyGroup Label="UserMacros" />
diff --git a/vsprojects/grpc_python_plugin/grpc_python_plugin.vcxproj b/vsprojects/grpc_python_plugin/grpc_python_plugin.vcxproj
index 02bab1c..a1e3a4a 100644
--- a/vsprojects/grpc_python_plugin/grpc_python_plugin.vcxproj
+++ b/vsprojects/grpc_python_plugin/grpc_python_plugin.vcxproj
@@ -48,6 +48,7 @@
   <ImportGroup Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
     <Import Project="..\protoc.props" />
+    <Import Project="..\protobuf.props" />
     <Import Project="..\global.props" />
   </ImportGroup>
   <PropertyGroup Label="UserMacros" />
diff --git a/vsprojects/grpc_ruby_plugin/grpc_ruby_plugin.vcxproj b/vsprojects/grpc_ruby_plugin/grpc_ruby_plugin.vcxproj
index 4763d14..7f31678 100644
--- a/vsprojects/grpc_ruby_plugin/grpc_ruby_plugin.vcxproj
+++ b/vsprojects/grpc_ruby_plugin/grpc_ruby_plugin.vcxproj
@@ -48,6 +48,7 @@
   <ImportGroup Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
     <Import Project="..\protoc.props" />
+    <Import Project="..\protobuf.props" />
     <Import Project="..\global.props" />
   </ImportGroup>
   <PropertyGroup Label="UserMacros" />
diff --git a/vsprojects/protobuf.props b/vsprojects/protobuf.props
index d2685f7..4a3c492 100644
--- a/vsprojects/protobuf.props
+++ b/vsprojects/protobuf.props
@@ -6,7 +6,7 @@
   <ItemDefinitionGroup>

     <Link>

       <AdditionalDependencies>libprotobuf.lib;%(AdditionalDependencies)</AdditionalDependencies>

-      <AdditionalLibraryDirectories>$(ProjectDir)\..\..\third_party\protobuf\vsprojects\$(Configuration);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>

+      <AdditionalLibraryDirectories>$(ProjectDir)\..\..\third_party\protobuf\cmake\$(Configuration);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>

     </Link>

   </ItemDefinitionGroup>

   <ItemGroup />

diff --git a/vsprojects/protoc.props b/vsprojects/protoc.props
index 6024022..fc89694 100644
--- a/vsprojects/protoc.props
+++ b/vsprojects/protoc.props
@@ -6,7 +6,7 @@
   <ItemDefinitionGroup>

     <Link>

       <AdditionalDependencies>libprotoc.lib;%(AdditionalDependencies)</AdditionalDependencies>

-      <AdditionalLibraryDirectories>$(ProjectDir)\..\..\third_party\protobuf\vsprojects\$(Configuration);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>

+      <AdditionalLibraryDirectories>$(ProjectDir)\..\..\third_party\protobuf\cmake\$(Configuration);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>

     </Link>

   </ItemDefinitionGroup>

   <ItemGroup />