Merge pull request #7962 from y-zeng/call_holder_add_pollent

Add calls' polling entities to the pollset_set of client_channel
diff --git a/README.md b/README.md
index e9b0454..70cf9fc 100644
--- a/README.md
+++ b/README.md
@@ -21,7 +21,7 @@
 
 This repository contains source code for gRPC libraries for multiple languages written on top of shared C core library [src/core] (src/core).
 
-Libraries in different languages are in different states of development. We are seeking contributions for all of these libraries.
+Libraries in different languages may be in different states of development. We are seeking contributions for all of these libraries.
 
 | Language                | Source                              | Status  |
 |-------------------------|-------------------------------------|---------|
diff --git a/doc/interop-test-descriptions.md b/doc/interop-test-descriptions.md
index 1e049663..666af18 100644
--- a/doc/interop-test-descriptions.md
+++ b/doc/interop-test-descriptions.md
@@ -60,6 +60,35 @@
 *It may be possible to use UnaryCall instead of EmptyCall, but it is harder to
 ensure that the proto serialized to zero bytes.*
 
+### cacheable_unary
+
+This test verifies that gRPC requests marked as cacheable use GET verb instead
+of POST, and that server sets appropriate cache control headers for the response
+to be cached by a proxy. This test requires that the server is behind
+a caching proxy. Use of current timestamp in the request prevents accidental
+cache matches left over from previous tests.
+
+Server features:
+* [CacheableUnaryCall][]
+
+Procedure:
+ 1. Client calls CacheableUnaryCall with `SimpleRequest` request with payload
+    set to current timestamp. Timestamp format is irrelevant, and resolution is
+    in nanoseconds.
+    Client adds a `x-user-ip` header with value `1.2.3.4` to the request.
+    This is done since some proxys such as GFE will not cache requests from
+    localhost.
+    Client marks the request as cacheable by setting the cacheable flag in the
+    request context. Longer term this should be driven by the method option
+    specified in the proto file itself.
+ 2. Client calls CacheableUnaryCall with `SimpleRequest` request again
+    immediately with the same payload as the previous request. Cacheable flag is
+    also set for this request's context.
+
+Client asserts:
+* Both calls were successful
+* The payload body of both responses is the same.
+
 ### large_unary
 
 This test verifies unary calls succeed in sending messages, and touches on flow
@@ -941,6 +970,18 @@
 for the `SimpleRequest.response_type`. If the server does not support the
 `response_type`, then it should fail the RPC with `INVALID_ARGUMENT`.
 
+### CacheableUnaryCall
+
+Server gets the default SimpleRequest proto as the request. The content of the
+request is ignored. It returns the SimpleResponse proto with the payload set
+to current timestamp.  The timestamp is an integer representing current time
+with nanosecond resolution. This integer is formated as ASCII decimal in the
+response. The format is not really important as long as the response payload
+is different for each request. In addition it adds
+  1. cache control headers such that the response can be cached by proxies in
+     the response path. Server should be behind a caching proxy for this test
+     to pass. Currently we set the max-age to 60 seconds.
+
 ### CompressedResponse
 [CompressedResponse]: #compressedresponse
 
diff --git a/src/compiler/README.md b/src/compiler/README.md
new file mode 100644
index 0000000..a2f49b3
--- /dev/null
+++ b/src/compiler/README.md
@@ -0,0 +1,4 @@
+#Overview
+
+This directory contains source code for gRPC protocol buffer compiler (*protoc*) plugins. Along with `protoc`,
+these plugins are used to generate gRPC client and server stubs from `.proto` files.
diff --git a/src/compiler/csharp_generator.cc b/src/compiler/csharp_generator.cc
index 591e5ae..4815703 100644
--- a/src/compiler/csharp_generator.cc
+++ b/src/compiler/csharp_generator.cc
@@ -495,6 +495,9 @@
 
   // override NewInstance method
   out->Print(
+      "/// <summary>Creates a new instance of client from given "
+      "<c>ClientBaseConfiguration</c>.</summary>\n");
+  out->Print(
       "protected override $name$ NewInstance(ClientBaseConfiguration "
       "configuration)\n",
       "name", GetClientClassName(service));
diff --git a/src/core/README.md b/src/core/README.md
index 0d8c0d5..44c6f24 100644
--- a/src/core/README.md
+++ b/src/core/README.md
@@ -1,8 +1,4 @@
 #Overview
 
-This directory contains source code for shared C library. Libraries in other languages in this repository (C++, Ruby,
+This directory contains source code for C library (a.k.a the *gRPC C core*) that provides all gRPC's core functionality through a low level API. Libraries in other languages in this repository (C++, Ruby,
 Python, PHP, NodeJS, Objective-C) are layered on top of this library.
-
-#Status
-
-Beta
diff --git a/src/core/ext/lb_policy/grpclb/grpclb.c b/src/core/ext/lb_policy/grpclb/grpclb.c
index 29d8485..66eced1 100644
--- a/src/core/ext/lb_policy/grpclb/grpclb.c
+++ b/src/core/ext/lb_policy/grpclb/grpclb.c
@@ -329,8 +329,8 @@
   if (server->port >> 16 != 0) {
     if (log) {
       gpr_log(GPR_ERROR,
-              "Invalid port '%d' at index %zu of serverlist. Ignoring.",
-              server->port, idx);
+              "Invalid port '%d' at index %lu of serverlist. Ignoring.",
+              server->port, (unsigned long)idx);
     }
     return false;
   }
@@ -338,9 +338,9 @@
   if (ip->size != 4 && ip->size != 16) {
     if (log) {
       gpr_log(GPR_ERROR,
-              "Expected IP to be 4 or 16 bytes, got %d at index %zu of "
+              "Expected IP to be 4 or 16 bytes, got %d at index %lu of "
               "serverlist. Ignoring",
-              ip->size, idx);
+              ip->size, (unsigned long)idx);
     }
     return false;
   }
@@ -1067,8 +1067,8 @@
     if (serverlist != NULL) {
       gpr_slice_unref(response_slice);
       if (grpc_lb_glb_trace) {
-        gpr_log(GPR_INFO, "Serverlist with %zu servers received",
-                serverlist->num_servers);
+        gpr_log(GPR_INFO, "Serverlist with %lu servers received",
+                (unsigned long)serverlist->num_servers);
       }
 
       /* update serverlist */
@@ -1152,10 +1152,10 @@
   if (grpc_lb_glb_trace) {
     gpr_log(GPR_INFO,
             "status from lb server received. Status = %d, Details = '%s', "
-            "Capaticy "
-            "= %zu",
+            "Capacity "
+            "= %lu",
             lb_client->status, lb_client->status_details,
-            lb_client->status_details_capacity);
+            (unsigned long)lb_client->status_details_capacity);
   }
   /* TODO(dgq): deal with stream termination properly (fire up another one?
    * fail the original call?) */
diff --git a/src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c b/src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c
index da3e284..563271f 100644
--- a/src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c
+++ b/src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c
@@ -61,13 +61,12 @@
   grpc_server_credentials *creds;
   bool is_shutdown;
   gpr_mu mu;
-  gpr_refcount refcount;
-  grpc_closure destroy_closure;
-  grpc_closure *destroy_callback;
+  grpc_closure tcp_server_shutdown_complete;
+  grpc_closure *server_destroy_listener_done;
 } server_secure_state;
 
 typedef struct server_secure_connect {
-  server_secure_state *state;
+  server_secure_state *server_state;
   grpc_pollset *accepting_pollset;
   grpc_tcp_server_acceptor *acceptor;
   grpc_handshake_manager *handshake_mgr;
@@ -77,39 +76,28 @@
   grpc_channel_args *args;
 } server_secure_connect;
 
-static void state_ref(server_secure_state *state) { gpr_ref(&state->refcount); }
-
-static void state_unref(server_secure_state *state) {
-  if (gpr_unref(&state->refcount)) {
-    /* ensure all threads have unlocked */
-    gpr_mu_lock(&state->mu);
-    gpr_mu_unlock(&state->mu);
-    /* clean up */
-    GRPC_SECURITY_CONNECTOR_UNREF(&state->sc->base, "server");
-    grpc_server_credentials_unref(state->creds);
-    gpr_free(state);
-  }
-}
-
 static void on_secure_handshake_done(grpc_exec_ctx *exec_ctx, void *statep,
                                      grpc_security_status status,
                                      grpc_endpoint *secure_endpoint,
                                      grpc_auth_context *auth_context) {
-  server_secure_connect *state = statep;
+  server_secure_connect *connection_state = statep;
   if (status == GRPC_SECURITY_OK) {
     if (secure_endpoint) {
-      gpr_mu_lock(&state->state->mu);
-      if (!state->state->is_shutdown) {
+      gpr_mu_lock(&connection_state->server_state->mu);
+      if (!connection_state->server_state->is_shutdown) {
         grpc_transport *transport = grpc_create_chttp2_transport(
-            exec_ctx, grpc_server_get_channel_args(state->state->server),
+            exec_ctx, grpc_server_get_channel_args(
+                          connection_state->server_state->server),
             secure_endpoint, 0);
         grpc_arg args_to_add[2];
-        args_to_add[0] = grpc_server_credentials_to_arg(state->state->creds);
+        args_to_add[0] = grpc_server_credentials_to_arg(
+            connection_state->server_state->creds);
         args_to_add[1] = grpc_auth_context_to_arg(auth_context);
         grpc_channel_args *args_copy = grpc_channel_args_copy_and_add(
-            state->args, args_to_add, GPR_ARRAY_SIZE(args_to_add));
-        grpc_server_setup_transport(exec_ctx, state->state->server, transport,
-                                    state->accepting_pollset, args_copy);
+            connection_state->args, args_to_add, GPR_ARRAY_SIZE(args_to_add));
+        grpc_server_setup_transport(
+            exec_ctx, connection_state->server_state->server, transport,
+            connection_state->accepting_pollset, args_copy);
         grpc_channel_args_destroy(args_copy);
         grpc_chttp2_transport_start_reading(exec_ctx, transport, NULL);
       } else {
@@ -117,21 +105,21 @@
          * gone away. */
         grpc_endpoint_destroy(exec_ctx, secure_endpoint);
       }
-      gpr_mu_unlock(&state->state->mu);
+      gpr_mu_unlock(&connection_state->server_state->mu);
     }
   } else {
     gpr_log(GPR_ERROR, "Secure transport failed with error %d", status);
   }
-  grpc_channel_args_destroy(state->args);
-  state_unref(state->state);
-  gpr_free(state);
+  grpc_channel_args_destroy(connection_state->args);
+  grpc_tcp_server_unref(exec_ctx, connection_state->server_state->tcp);
+  gpr_free(connection_state);
 }
 
 static void on_handshake_done(grpc_exec_ctx *exec_ctx, grpc_endpoint *endpoint,
                               grpc_channel_args *args,
                               gpr_slice_buffer *read_buffer, void *user_data,
                               grpc_error *error) {
-  server_secure_connect *state = user_data;
+  server_secure_connect *connection_state = user_data;
   if (error != GRPC_ERROR_NONE) {
     const char *error_str = grpc_error_string(error);
     gpr_log(GPR_ERROR, "Handshaking failed: %s", error_str);
@@ -139,81 +127,107 @@
     GRPC_ERROR_UNREF(error);
     grpc_channel_args_destroy(args);
     gpr_free(read_buffer);
-    grpc_handshake_manager_shutdown(exec_ctx, state->handshake_mgr);
-    grpc_handshake_manager_destroy(exec_ctx, state->handshake_mgr);
-    state_unref(state->state);
-    gpr_free(state);
+    grpc_handshake_manager_shutdown(exec_ctx, connection_state->handshake_mgr);
+    grpc_handshake_manager_destroy(exec_ctx, connection_state->handshake_mgr);
+    grpc_tcp_server_unref(exec_ctx, connection_state->server_state->tcp);
+    gpr_free(connection_state);
     return;
   }
-  grpc_handshake_manager_destroy(exec_ctx, state->handshake_mgr);
-  state->handshake_mgr = NULL;
+  grpc_handshake_manager_destroy(exec_ctx, connection_state->handshake_mgr);
+  connection_state->handshake_mgr = NULL;
   // TODO(roth, jboeuf): Convert security connector handshaking to use new
   // handshake API, and then move the code from on_secure_handshake_done()
   // into this function.
-  state->args = args;
+  connection_state->args = args;
   grpc_server_security_connector_do_handshake(
-      exec_ctx, state->state->sc, state->acceptor, endpoint, read_buffer,
-      state->deadline, on_secure_handshake_done, state);
+      exec_ctx, connection_state->server_state->sc, connection_state->acceptor,
+      endpoint, read_buffer, connection_state->deadline,
+      on_secure_handshake_done, connection_state);
 }
 
 static void on_accept(grpc_exec_ctx *exec_ctx, void *statep, grpc_endpoint *tcp,
                       grpc_pollset *accepting_pollset,
                       grpc_tcp_server_acceptor *acceptor) {
-  server_secure_connect *state = gpr_malloc(sizeof(*state));
-  state->state = statep;
-  state_ref(state->state);
-  state->accepting_pollset = accepting_pollset;
-  state->acceptor = acceptor;
-  state->handshake_mgr = grpc_handshake_manager_create();
+  server_secure_state *server_state = statep;
+  server_secure_connect *connection_state = NULL;
+  gpr_mu_lock(&server_state->mu);
+  if (server_state->is_shutdown) {
+    gpr_mu_unlock(&server_state->mu);
+    grpc_endpoint_destroy(exec_ctx, tcp);
+    return;
+  }
+  gpr_mu_unlock(&server_state->mu);
+  grpc_tcp_server_ref(server_state->tcp);
+  connection_state = gpr_malloc(sizeof(*connection_state));
+  connection_state->server_state = server_state;
+  connection_state->accepting_pollset = accepting_pollset;
+  connection_state->acceptor = acceptor;
+  connection_state->handshake_mgr = grpc_handshake_manager_create();
   // TODO(roth): We should really get this timeout value from channel
   // args instead of hard-coding it.
-  state->deadline = gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC),
-                                 gpr_time_from_seconds(120, GPR_TIMESPAN));
+  connection_state->deadline = gpr_time_add(
+      gpr_now(GPR_CLOCK_MONOTONIC), gpr_time_from_seconds(120, GPR_TIMESPAN));
   grpc_handshake_manager_do_handshake(
-      exec_ctx, state->handshake_mgr, tcp,
-      grpc_server_get_channel_args(state->state->server), state->deadline,
-      acceptor, on_handshake_done, state);
+      exec_ctx, connection_state->handshake_mgr, tcp,
+      grpc_server_get_channel_args(connection_state->server_state->server),
+      connection_state->deadline, acceptor, on_handshake_done,
+      connection_state);
 }
 
 /* Server callback: start listening on our ports */
-static void start(grpc_exec_ctx *exec_ctx, grpc_server *server, void *statep,
-                  grpc_pollset **pollsets, size_t pollset_count) {
-  server_secure_state *state = statep;
-  grpc_tcp_server_start(exec_ctx, state->tcp, pollsets, pollset_count,
-                        on_accept, state);
+static void server_start_listener(grpc_exec_ctx *exec_ctx, grpc_server *server,
+                                  void *statep, grpc_pollset **pollsets,
+                                  size_t pollset_count) {
+  server_secure_state *server_state = statep;
+  gpr_mu_lock(&server_state->mu);
+  server_state->is_shutdown = false;
+  gpr_mu_unlock(&server_state->mu);
+  grpc_tcp_server_start(exec_ctx, server_state->tcp, pollsets, pollset_count,
+                        on_accept, server_state);
 }
 
-static void destroy_done(grpc_exec_ctx *exec_ctx, void *statep,
-                         grpc_error *error) {
-  server_secure_state *state = statep;
-  if (state->destroy_callback != NULL) {
-    state->destroy_callback->cb(exec_ctx, state->destroy_callback->cb_arg,
-                                GRPC_ERROR_REF(error));
+static void tcp_server_shutdown_complete(grpc_exec_ctx *exec_ctx, void *statep,
+                                         grpc_error *error) {
+  server_secure_state *server_state = statep;
+  /* ensure all threads have unlocked */
+  gpr_mu_lock(&server_state->mu);
+  grpc_closure *destroy_done = server_state->server_destroy_listener_done;
+  GPR_ASSERT(server_state->is_shutdown);
+  gpr_mu_unlock(&server_state->mu);
+  /* clean up */
+  grpc_server_security_connector_shutdown(exec_ctx, server_state->sc);
+
+  /* Flush queued work before a synchronous unref. */
+  grpc_exec_ctx_flush(exec_ctx);
+  GRPC_SECURITY_CONNECTOR_UNREF(&server_state->sc->base, "server");
+  grpc_server_credentials_unref(server_state->creds);
+
+  if (destroy_done != NULL) {
+    destroy_done->cb(exec_ctx, destroy_done->cb_arg, GRPC_ERROR_REF(error));
+    grpc_exec_ctx_flush(exec_ctx);
   }
-  grpc_server_security_connector_shutdown(exec_ctx, state->sc);
-  state_unref(state);
+  gpr_free(server_state);
 }
 
-/* Server callback: destroy the tcp listener (so we don't generate further
-   callbacks) */
-static void destroy(grpc_exec_ctx *exec_ctx, grpc_server *server, void *statep,
-                    grpc_closure *callback) {
-  server_secure_state *state = statep;
+static void server_destroy_listener(grpc_exec_ctx *exec_ctx,
+                                    grpc_server *server, void *statep,
+                                    grpc_closure *callback) {
+  server_secure_state *server_state = statep;
   grpc_tcp_server *tcp;
-  gpr_mu_lock(&state->mu);
-  state->is_shutdown = true;
-  state->destroy_callback = callback;
-  tcp = state->tcp;
-  gpr_mu_unlock(&state->mu);
+  gpr_mu_lock(&server_state->mu);
+  server_state->is_shutdown = true;
+  server_state->server_destroy_listener_done = callback;
+  tcp = server_state->tcp;
+  gpr_mu_unlock(&server_state->mu);
   grpc_tcp_server_shutdown_listeners(exec_ctx, tcp);
-  grpc_tcp_server_unref(exec_ctx, tcp);
+  grpc_tcp_server_unref(exec_ctx, server_state->tcp);
 }
 
 int grpc_server_add_secure_http2_port(grpc_server *server, const char *addr,
                                       grpc_server_credentials *creds) {
   grpc_resolved_addresses *resolved = NULL;
   grpc_tcp_server *tcp = NULL;
-  server_secure_state *state = NULL;
+  server_secure_state *server_state = NULL;
   size_t i;
   size_t count = 0;
   int port_num = -1;
@@ -253,22 +267,22 @@
   if (err != GRPC_ERROR_NONE) {
     goto error;
   }
-  state = gpr_malloc(sizeof(*state));
-  memset(state, 0, sizeof(*state));
-  grpc_closure_init(&state->destroy_closure, destroy_done, state);
-  err = grpc_tcp_server_create(&state->destroy_closure,
+  server_state = gpr_malloc(sizeof(*server_state));
+  memset(server_state, 0, sizeof(*server_state));
+  grpc_closure_init(&server_state->tcp_server_shutdown_complete,
+                    tcp_server_shutdown_complete, server_state);
+  err = grpc_tcp_server_create(&server_state->tcp_server_shutdown_complete,
                                grpc_server_get_channel_args(server), &tcp);
   if (err != GRPC_ERROR_NONE) {
     goto error;
   }
 
-  state->server = server;
-  state->tcp = tcp;
-  state->sc = sc;
-  state->creds = grpc_server_credentials_ref(creds);
-  state->is_shutdown = false;
-  gpr_mu_init(&state->mu);
-  gpr_ref_init(&state->refcount, 1);
+  server_state->server = server;
+  server_state->tcp = tcp;
+  server_state->sc = sc;
+  server_state->creds = grpc_server_credentials_ref(creds);
+  server_state->is_shutdown = true;
+  gpr_mu_init(&server_state->mu);
 
   errors = gpr_malloc(sizeof(*errors) * resolved->naddrs);
   for (i = 0; i < resolved->naddrs; i++) {
@@ -313,7 +327,8 @@
   grpc_resolved_addresses_destroy(resolved);
 
   /* Register with the server only upon success */
-  grpc_server_add_listener(&exec_ctx, server, state, start, destroy);
+  grpc_server_add_listener(&exec_ctx, server, server_state,
+                           server_start_listener, server_destroy_listener);
 
   grpc_exec_ctx_finish(&exec_ctx);
   return port_num;
@@ -334,10 +349,11 @@
     grpc_tcp_server_unref(&exec_ctx, tcp);
   } else {
     if (sc) {
+      grpc_exec_ctx_flush(&exec_ctx);
       GRPC_SECURITY_CONNECTOR_UNREF(&sc->base, "server");
     }
-    if (state) {
-      gpr_free(state);
+    if (server_state) {
+      gpr_free(server_state);
     }
   }
   grpc_exec_ctx_finish(&exec_ctx);
diff --git a/src/core/lib/iomgr/tcp_server.h b/src/core/lib/iomgr/tcp_server.h
index 5a25d39..9a39069 100644
--- a/src/core/lib/iomgr/tcp_server.h
+++ b/src/core/lib/iomgr/tcp_server.h
@@ -101,8 +101,8 @@
 void grpc_tcp_server_shutdown_starting_add(grpc_tcp_server *s,
                                            grpc_closure *shutdown_starting);
 
-/* If the refcount drops to zero, delete s, and call (exec_ctx==NULL) or enqueue
-   a call (exec_ctx!=NULL) to shutdown_complete. */
+/* If the refcount drops to zero, enqueue calls on exec_ctx to
+   shutdown_listeners and delete s. */
 void grpc_tcp_server_unref(grpc_exec_ctx *exec_ctx, grpc_tcp_server *s);
 
 /* Shutdown the fds of listeners. */
diff --git a/src/core/lib/iomgr/tcp_server_posix.c b/src/core/lib/iomgr/tcp_server_posix.c
index 2d3f6cf..73df547 100644
--- a/src/core/lib/iomgr/tcp_server_posix.c
+++ b/src/core/lib/iomgr/tcp_server_posix.c
@@ -191,6 +191,9 @@
 }
 
 static void finish_shutdown(grpc_exec_ctx *exec_ctx, grpc_tcp_server *s) {
+  gpr_mu_lock(&s->mu);
+  GPR_ASSERT(s->shutdown);
+  gpr_mu_unlock(&s->mu);
   if (s->shutdown_complete != NULL) {
     grpc_exec_ctx_sched(exec_ctx, s->shutdown_complete, GRPC_ERROR_NONE, NULL);
   }
@@ -652,6 +655,7 @@
                                        unsigned port_index) {
   unsigned num_fds = 0;
   grpc_tcp_listener *sp;
+  gpr_mu_lock(&s->mu);
   for (sp = s->head; sp && port_index != 0; sp = sp->next) {
     if (!sp->is_sibling) {
       --port_index;
@@ -659,12 +663,15 @@
   }
   for (; sp; sp = sp->sibling, ++num_fds)
     ;
+  gpr_mu_unlock(&s->mu);
   return num_fds;
 }
 
 int grpc_tcp_server_port_fd(grpc_tcp_server *s, unsigned port_index,
                             unsigned fd_index) {
   grpc_tcp_listener *sp;
+  int fd;
+  gpr_mu_lock(&s->mu);
   for (sp = s->head; sp && port_index != 0; sp = sp->next) {
     if (!sp->is_sibling) {
       --port_index;
@@ -673,10 +680,12 @@
   for (; sp && fd_index != 0; sp = sp->sibling, --fd_index)
     ;
   if (sp) {
-    return sp->fd;
+    fd = sp->fd;
   } else {
-    return -1;
+    fd = -1;
   }
+  gpr_mu_unlock(&s->mu);
+  return fd;
 }
 
 void grpc_tcp_server_start(grpc_exec_ctx *exec_ctx, grpc_tcp_server *s,
@@ -722,7 +731,7 @@
 }
 
 grpc_tcp_server *grpc_tcp_server_ref(grpc_tcp_server *s) {
-  gpr_ref(&s->refs);
+  gpr_ref_non_zero(&s->refs);
   return s;
 }
 
@@ -736,19 +745,11 @@
 
 void grpc_tcp_server_unref(grpc_exec_ctx *exec_ctx, grpc_tcp_server *s) {
   if (gpr_unref(&s->refs)) {
-    /* Complete shutdown_starting work before destroying. */
-    grpc_exec_ctx local_exec_ctx = GRPC_EXEC_CTX_INIT;
+    grpc_tcp_server_shutdown_listeners(exec_ctx, s);
     gpr_mu_lock(&s->mu);
-    grpc_exec_ctx_enqueue_list(&local_exec_ctx, &s->shutdown_starting, NULL);
+    grpc_exec_ctx_enqueue_list(exec_ctx, &s->shutdown_starting, NULL);
     gpr_mu_unlock(&s->mu);
-    if (exec_ctx == NULL) {
-      grpc_exec_ctx_flush(&local_exec_ctx);
-      tcp_server_destroy(&local_exec_ctx, s);
-      grpc_exec_ctx_finish(&local_exec_ctx);
-    } else {
-      grpc_exec_ctx_finish(&local_exec_ctx);
-      tcp_server_destroy(exec_ctx, s);
-    }
+    tcp_server_destroy(exec_ctx, s);
   }
 }
 
diff --git a/src/core/lib/iomgr/tcp_server_windows.c b/src/core/lib/iomgr/tcp_server_windows.c
index 1b125e7..4ff0560 100644
--- a/src/core/lib/iomgr/tcp_server_windows.c
+++ b/src/core/lib/iomgr/tcp_server_windows.c
@@ -139,7 +139,7 @@
 }
 
 grpc_tcp_server *grpc_tcp_server_ref(grpc_tcp_server *s) {
-  gpr_ref(&s->refs);
+  gpr_ref_non_zero(&s->refs);
   return s;
 }
 
@@ -174,19 +174,11 @@
 
 void grpc_tcp_server_unref(grpc_exec_ctx *exec_ctx, grpc_tcp_server *s) {
   if (gpr_unref(&s->refs)) {
-    /* Complete shutdown_starting work before destroying. */
-    grpc_exec_ctx local_exec_ctx = GRPC_EXEC_CTX_INIT;
+    grpc_tcp_server_shutdown_listeners(exec_ctx, s);
     gpr_mu_lock(&s->mu);
-    grpc_exec_ctx_enqueue_list(&local_exec_ctx, &s->shutdown_starting, NULL);
+    grpc_exec_ctx_enqueue_list(exec_ctx, &s->shutdown_starting, NULL);
     gpr_mu_unlock(&s->mu);
-    if (exec_ctx == NULL) {
-      grpc_exec_ctx_flush(&local_exec_ctx);
-      tcp_server_destroy(&local_exec_ctx, s);
-      grpc_exec_ctx_finish(&local_exec_ctx);
-    } else {
-      grpc_exec_ctx_finish(&local_exec_ctx);
-      tcp_server_destroy(exec_ctx, s);
-    }
+    tcp_server_destroy(exec_ctx, s);
   }
 }
 
diff --git a/src/core/lib/security/credentials/composite/composite_credentials.c b/src/core/lib/security/credentials/composite/composite_credentials.c
index 850e41e..d55d00b 100644
--- a/src/core/lib/security/credentials/composite/composite_credentials.c
+++ b/src/core/lib/security/credentials/composite/composite_credentials.c
@@ -242,8 +242,17 @@
   return status;
 }
 
+static grpc_channel_credentials *
+composite_channel_duplicate_without_call_credentials(
+    grpc_channel_credentials *creds) {
+  grpc_composite_channel_credentials *c =
+      (grpc_composite_channel_credentials *)creds;
+  return grpc_channel_credentials_ref(c->inner_creds);
+}
+
 static grpc_channel_credentials_vtable composite_channel_credentials_vtable = {
-    composite_channel_destruct, composite_channel_create_security_connector};
+    composite_channel_destruct, composite_channel_create_security_connector,
+    composite_channel_duplicate_without_call_credentials};
 
 grpc_channel_credentials *grpc_composite_channel_credentials_create(
     grpc_channel_credentials *channel_creds, grpc_call_credentials *call_creds,
diff --git a/src/core/lib/security/credentials/composite/composite_credentials.h b/src/core/lib/security/credentials/composite/composite_credentials.h
index 0d8966f..f8425c2 100644
--- a/src/core/lib/security/credentials/composite/composite_credentials.h
+++ b/src/core/lib/security/credentials/composite/composite_credentials.h
@@ -53,7 +53,7 @@
     grpc_call_credentials *creds, const char *type,
     grpc_call_credentials **composite_creds);
 
-/* -- Channel composite credentials. -- */
+/* -- Composite channel credentials. -- */
 
 typedef struct {
   grpc_channel_credentials base;
@@ -61,7 +61,7 @@
   grpc_call_credentials *call_creds;
 } grpc_composite_channel_credentials;
 
-/* -- Composite credentials. -- */
+/* -- Composite call credentials. -- */
 
 typedef struct {
   grpc_call_credentials base;
diff --git a/src/core/lib/security/credentials/credentials.c b/src/core/lib/security/credentials/credentials.c
index 029a357..1149e5c 100644
--- a/src/core/lib/security/credentials/credentials.c
+++ b/src/core/lib/security/credentials/credentials.c
@@ -138,6 +138,18 @@
       channel_creds, NULL, target, args, sc, new_args);
 }
 
+grpc_channel_credentials *
+grpc_channel_credentials_duplicate_without_call_credentials(
+    grpc_channel_credentials *channel_creds) {
+  if (channel_creds != NULL && channel_creds->vtable != NULL &&
+      channel_creds->vtable->duplicate_without_call_credentials != NULL) {
+    return channel_creds->vtable->duplicate_without_call_credentials(
+        channel_creds);
+  } else {
+    return grpc_channel_credentials_ref(channel_creds);
+  }
+}
+
 grpc_server_credentials *grpc_server_credentials_ref(
     grpc_server_credentials *creds) {
   if (creds == NULL) return NULL;
diff --git a/src/core/lib/security/credentials/credentials.h b/src/core/lib/security/credentials/credentials.h
index 8e9d842..6fb5b5b 100644
--- a/src/core/lib/security/credentials/credentials.h
+++ b/src/core/lib/security/credentials/credentials.h
@@ -107,6 +107,9 @@
       grpc_channel_credentials *c, grpc_call_credentials *call_creds,
       const char *target, const grpc_channel_args *args,
       grpc_channel_security_connector **sc, grpc_channel_args **new_args);
+
+  grpc_channel_credentials *(*duplicate_without_call_credentials)(
+      grpc_channel_credentials *c);
 } grpc_channel_credentials_vtable;
 
 struct grpc_channel_credentials {
@@ -128,6 +131,13 @@
     const grpc_channel_args *args, grpc_channel_security_connector **sc,
     grpc_channel_args **new_args);
 
+/* Creates a version of the channel credentials without any attached call
+   credentials. This can be used in order to open a channel to a non-trusted
+   gRPC load balancer. */
+grpc_channel_credentials *
+grpc_channel_credentials_duplicate_without_call_credentials(
+    grpc_channel_credentials *creds);
+
 /* --- grpc_credentials_md. --- */
 
 typedef struct {
diff --git a/src/core/lib/security/credentials/fake/fake_credentials.c b/src/core/lib/security/credentials/fake/fake_credentials.c
index 51cafd9..ea4cb76 100644
--- a/src/core/lib/security/credentials/fake/fake_credentials.c
+++ b/src/core/lib/security/credentials/fake/fake_credentials.c
@@ -61,7 +61,7 @@
 
 static grpc_channel_credentials_vtable
     fake_transport_security_credentials_vtable = {
-        NULL, fake_transport_security_create_security_connector};
+        NULL, fake_transport_security_create_security_connector, NULL};
 
 static grpc_server_credentials_vtable
     fake_transport_security_server_credentials_vtable = {
diff --git a/src/core/lib/security/credentials/ssl/ssl_credentials.c b/src/core/lib/security/credentials/ssl/ssl_credentials.c
index 545bca9..0dc1fcc 100644
--- a/src/core/lib/security/credentials/ssl/ssl_credentials.c
+++ b/src/core/lib/security/credentials/ssl/ssl_credentials.c
@@ -95,7 +95,7 @@
 }
 
 static grpc_channel_credentials_vtable ssl_vtable = {
-    ssl_destruct, ssl_create_security_connector};
+    ssl_destruct, ssl_create_security_connector, NULL};
 
 static void ssl_build_config(const char *pem_root_certs,
                              grpc_ssl_pem_key_cert_pair *pem_key_cert_pair,
diff --git a/src/cpp/README.md b/src/cpp/README.md
index 8c0f85e..d9b5213 100644
--- a/src/cpp/README.md
+++ b/src/cpp/README.md
@@ -3,10 +3,6 @@
 
 This directory contains source code for C++ implementation of gRPC.
 
-#Status
-
-Beta
-
 #Pre-requisites
 
 ##Linux
diff --git a/src/csharp/Grpc.Examples/Math.cs b/src/csharp/Grpc.Examples/Math.cs
index a17228c..fae4fd3 100644
--- a/src/csharp/Grpc.Examples/Math.cs
+++ b/src/csharp/Grpc.Examples/Math.cs
@@ -10,7 +10,6 @@
 namespace Math {
 
   /// <summary>Holder for reflection information generated from math.proto</summary>
-  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
   public static partial class MathReflection {
 
     #region Descriptor
@@ -46,30 +45,35 @@
 
   }
   #region Messages
-  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
   public sealed partial class DivArgs : pb::IMessage<DivArgs> {
     private static readonly pb::MessageParser<DivArgs> _parser = new pb::MessageParser<DivArgs>(() => new DivArgs());
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pb::MessageParser<DivArgs> Parser { get { return _parser; } }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pbr::MessageDescriptor Descriptor {
       get { return global::Math.MathReflection.Descriptor.MessageTypes[0]; }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     pbr::MessageDescriptor pb::IMessage.Descriptor {
       get { return Descriptor; }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public DivArgs() {
       OnConstruction();
     }
 
     partial void OnConstruction();
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public DivArgs(DivArgs other) : this() {
       dividend_ = other.dividend_;
       divisor_ = other.divisor_;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public DivArgs Clone() {
       return new DivArgs(this);
     }
@@ -77,6 +81,7 @@
     /// <summary>Field number for the "dividend" field.</summary>
     public const int DividendFieldNumber = 1;
     private long dividend_;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public long Dividend {
       get { return dividend_; }
       set {
@@ -87,6 +92,7 @@
     /// <summary>Field number for the "divisor" field.</summary>
     public const int DivisorFieldNumber = 2;
     private long divisor_;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public long Divisor {
       get { return divisor_; }
       set {
@@ -94,10 +100,12 @@
       }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override bool Equals(object other) {
       return Equals(other as DivArgs);
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public bool Equals(DivArgs other) {
       if (ReferenceEquals(other, null)) {
         return false;
@@ -110,6 +118,7 @@
       return true;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override int GetHashCode() {
       int hash = 1;
       if (Dividend != 0L) hash ^= Dividend.GetHashCode();
@@ -117,10 +126,12 @@
       return hash;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override string ToString() {
       return pb::JsonFormatter.ToDiagnosticString(this);
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void WriteTo(pb::CodedOutputStream output) {
       if (Dividend != 0L) {
         output.WriteRawTag(8);
@@ -132,6 +143,7 @@
       }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public int CalculateSize() {
       int size = 0;
       if (Dividend != 0L) {
@@ -143,6 +155,7 @@
       return size;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void MergeFrom(DivArgs other) {
       if (other == null) {
         return;
@@ -155,6 +168,7 @@
       }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void MergeFrom(pb::CodedInputStream input) {
       uint tag;
       while ((tag = input.ReadTag()) != 0) {
@@ -176,30 +190,35 @@
 
   }
 
-  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
   public sealed partial class DivReply : pb::IMessage<DivReply> {
     private static readonly pb::MessageParser<DivReply> _parser = new pb::MessageParser<DivReply>(() => new DivReply());
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pb::MessageParser<DivReply> Parser { get { return _parser; } }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pbr::MessageDescriptor Descriptor {
       get { return global::Math.MathReflection.Descriptor.MessageTypes[1]; }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     pbr::MessageDescriptor pb::IMessage.Descriptor {
       get { return Descriptor; }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public DivReply() {
       OnConstruction();
     }
 
     partial void OnConstruction();
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public DivReply(DivReply other) : this() {
       quotient_ = other.quotient_;
       remainder_ = other.remainder_;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public DivReply Clone() {
       return new DivReply(this);
     }
@@ -207,6 +226,7 @@
     /// <summary>Field number for the "quotient" field.</summary>
     public const int QuotientFieldNumber = 1;
     private long quotient_;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public long Quotient {
       get { return quotient_; }
       set {
@@ -217,6 +237,7 @@
     /// <summary>Field number for the "remainder" field.</summary>
     public const int RemainderFieldNumber = 2;
     private long remainder_;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public long Remainder {
       get { return remainder_; }
       set {
@@ -224,10 +245,12 @@
       }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override bool Equals(object other) {
       return Equals(other as DivReply);
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public bool Equals(DivReply other) {
       if (ReferenceEquals(other, null)) {
         return false;
@@ -240,6 +263,7 @@
       return true;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override int GetHashCode() {
       int hash = 1;
       if (Quotient != 0L) hash ^= Quotient.GetHashCode();
@@ -247,10 +271,12 @@
       return hash;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override string ToString() {
       return pb::JsonFormatter.ToDiagnosticString(this);
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void WriteTo(pb::CodedOutputStream output) {
       if (Quotient != 0L) {
         output.WriteRawTag(8);
@@ -262,6 +288,7 @@
       }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public int CalculateSize() {
       int size = 0;
       if (Quotient != 0L) {
@@ -273,6 +300,7 @@
       return size;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void MergeFrom(DivReply other) {
       if (other == null) {
         return;
@@ -285,6 +313,7 @@
       }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void MergeFrom(pb::CodedInputStream input) {
       uint tag;
       while ((tag = input.ReadTag()) != 0) {
@@ -306,29 +335,34 @@
 
   }
 
-  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
   public sealed partial class FibArgs : pb::IMessage<FibArgs> {
     private static readonly pb::MessageParser<FibArgs> _parser = new pb::MessageParser<FibArgs>(() => new FibArgs());
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pb::MessageParser<FibArgs> Parser { get { return _parser; } }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pbr::MessageDescriptor Descriptor {
       get { return global::Math.MathReflection.Descriptor.MessageTypes[2]; }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     pbr::MessageDescriptor pb::IMessage.Descriptor {
       get { return Descriptor; }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public FibArgs() {
       OnConstruction();
     }
 
     partial void OnConstruction();
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public FibArgs(FibArgs other) : this() {
       limit_ = other.limit_;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public FibArgs Clone() {
       return new FibArgs(this);
     }
@@ -336,6 +370,7 @@
     /// <summary>Field number for the "limit" field.</summary>
     public const int LimitFieldNumber = 1;
     private long limit_;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public long Limit {
       get { return limit_; }
       set {
@@ -343,10 +378,12 @@
       }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override bool Equals(object other) {
       return Equals(other as FibArgs);
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public bool Equals(FibArgs other) {
       if (ReferenceEquals(other, null)) {
         return false;
@@ -358,16 +395,19 @@
       return true;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override int GetHashCode() {
       int hash = 1;
       if (Limit != 0L) hash ^= Limit.GetHashCode();
       return hash;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override string ToString() {
       return pb::JsonFormatter.ToDiagnosticString(this);
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void WriteTo(pb::CodedOutputStream output) {
       if (Limit != 0L) {
         output.WriteRawTag(8);
@@ -375,6 +415,7 @@
       }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public int CalculateSize() {
       int size = 0;
       if (Limit != 0L) {
@@ -383,6 +424,7 @@
       return size;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void MergeFrom(FibArgs other) {
       if (other == null) {
         return;
@@ -392,6 +434,7 @@
       }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void MergeFrom(pb::CodedInputStream input) {
       uint tag;
       while ((tag = input.ReadTag()) != 0) {
@@ -409,29 +452,34 @@
 
   }
 
-  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
   public sealed partial class Num : pb::IMessage<Num> {
     private static readonly pb::MessageParser<Num> _parser = new pb::MessageParser<Num>(() => new Num());
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pb::MessageParser<Num> Parser { get { return _parser; } }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pbr::MessageDescriptor Descriptor {
       get { return global::Math.MathReflection.Descriptor.MessageTypes[3]; }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     pbr::MessageDescriptor pb::IMessage.Descriptor {
       get { return Descriptor; }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public Num() {
       OnConstruction();
     }
 
     partial void OnConstruction();
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public Num(Num other) : this() {
       num_ = other.num_;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public Num Clone() {
       return new Num(this);
     }
@@ -439,6 +487,7 @@
     /// <summary>Field number for the "num" field.</summary>
     public const int Num_FieldNumber = 1;
     private long num_;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public long Num_ {
       get { return num_; }
       set {
@@ -446,10 +495,12 @@
       }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override bool Equals(object other) {
       return Equals(other as Num);
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public bool Equals(Num other) {
       if (ReferenceEquals(other, null)) {
         return false;
@@ -461,16 +512,19 @@
       return true;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override int GetHashCode() {
       int hash = 1;
       if (Num_ != 0L) hash ^= Num_.GetHashCode();
       return hash;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override string ToString() {
       return pb::JsonFormatter.ToDiagnosticString(this);
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void WriteTo(pb::CodedOutputStream output) {
       if (Num_ != 0L) {
         output.WriteRawTag(8);
@@ -478,6 +532,7 @@
       }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public int CalculateSize() {
       int size = 0;
       if (Num_ != 0L) {
@@ -486,6 +541,7 @@
       return size;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void MergeFrom(Num other) {
       if (other == null) {
         return;
@@ -495,6 +551,7 @@
       }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void MergeFrom(pb::CodedInputStream input) {
       uint tag;
       while ((tag = input.ReadTag()) != 0) {
@@ -512,29 +569,34 @@
 
   }
 
-  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
   public sealed partial class FibReply : pb::IMessage<FibReply> {
     private static readonly pb::MessageParser<FibReply> _parser = new pb::MessageParser<FibReply>(() => new FibReply());
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pb::MessageParser<FibReply> Parser { get { return _parser; } }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pbr::MessageDescriptor Descriptor {
       get { return global::Math.MathReflection.Descriptor.MessageTypes[4]; }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     pbr::MessageDescriptor pb::IMessage.Descriptor {
       get { return Descriptor; }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public FibReply() {
       OnConstruction();
     }
 
     partial void OnConstruction();
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public FibReply(FibReply other) : this() {
       count_ = other.count_;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public FibReply Clone() {
       return new FibReply(this);
     }
@@ -542,6 +604,7 @@
     /// <summary>Field number for the "count" field.</summary>
     public const int CountFieldNumber = 1;
     private long count_;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public long Count {
       get { return count_; }
       set {
@@ -549,10 +612,12 @@
       }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override bool Equals(object other) {
       return Equals(other as FibReply);
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public bool Equals(FibReply other) {
       if (ReferenceEquals(other, null)) {
         return false;
@@ -564,16 +629,19 @@
       return true;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override int GetHashCode() {
       int hash = 1;
       if (Count != 0L) hash ^= Count.GetHashCode();
       return hash;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override string ToString() {
       return pb::JsonFormatter.ToDiagnosticString(this);
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void WriteTo(pb::CodedOutputStream output) {
       if (Count != 0L) {
         output.WriteRawTag(8);
@@ -581,6 +649,7 @@
       }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public int CalculateSize() {
       int size = 0;
       if (Count != 0L) {
@@ -589,6 +658,7 @@
       return size;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void MergeFrom(FibReply other) {
       if (other == null) {
         return;
@@ -598,6 +668,7 @@
       }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void MergeFrom(pb::CodedInputStream input) {
       uint tag;
       while ((tag = input.ReadTag()) != 0) {
diff --git a/src/csharp/Grpc.Examples/MathGrpc.cs b/src/csharp/Grpc.Examples/MathGrpc.cs
index 25abc51..d6ba61e7 100644
--- a/src/csharp/Grpc.Examples/MathGrpc.cs
+++ b/src/csharp/Grpc.Examples/MathGrpc.cs
@@ -234,6 +234,7 @@
       {
         return CallInvoker.AsyncClientStreamingCall(__Method_Sum, null, options);
       }
+      /// <summary>Creates a new instance of client from given <c>ClientBaseConfiguration</c>.</summary>
       protected override MathClient NewInstance(ClientBaseConfiguration configuration)
       {
         return new MathClient(configuration);
diff --git a/src/csharp/Grpc.HealthCheck/Health.cs b/src/csharp/Grpc.HealthCheck/Health.cs
index 100ad18..b8e2e22 100644
--- a/src/csharp/Grpc.HealthCheck/Health.cs
+++ b/src/csharp/Grpc.HealthCheck/Health.cs
@@ -10,7 +10,6 @@
 namespace Grpc.Health.V1 {
 
   /// <summary>Holder for reflection information generated from health.proto</summary>
-  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
   public static partial class HealthReflection {
 
     #region Descriptor
@@ -42,29 +41,34 @@
 
   }
   #region Messages
-  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
   public sealed partial class HealthCheckRequest : pb::IMessage<HealthCheckRequest> {
     private static readonly pb::MessageParser<HealthCheckRequest> _parser = new pb::MessageParser<HealthCheckRequest>(() => new HealthCheckRequest());
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pb::MessageParser<HealthCheckRequest> Parser { get { return _parser; } }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pbr::MessageDescriptor Descriptor {
       get { return global::Grpc.Health.V1.HealthReflection.Descriptor.MessageTypes[0]; }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     pbr::MessageDescriptor pb::IMessage.Descriptor {
       get { return Descriptor; }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public HealthCheckRequest() {
       OnConstruction();
     }
 
     partial void OnConstruction();
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public HealthCheckRequest(HealthCheckRequest other) : this() {
       service_ = other.service_;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public HealthCheckRequest Clone() {
       return new HealthCheckRequest(this);
     }
@@ -72,6 +76,7 @@
     /// <summary>Field number for the "service" field.</summary>
     public const int ServiceFieldNumber = 1;
     private string service_ = "";
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public string Service {
       get { return service_; }
       set {
@@ -79,10 +84,12 @@
       }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override bool Equals(object other) {
       return Equals(other as HealthCheckRequest);
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public bool Equals(HealthCheckRequest other) {
       if (ReferenceEquals(other, null)) {
         return false;
@@ -94,16 +101,19 @@
       return true;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override int GetHashCode() {
       int hash = 1;
       if (Service.Length != 0) hash ^= Service.GetHashCode();
       return hash;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override string ToString() {
       return pb::JsonFormatter.ToDiagnosticString(this);
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void WriteTo(pb::CodedOutputStream output) {
       if (Service.Length != 0) {
         output.WriteRawTag(10);
@@ -111,6 +121,7 @@
       }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public int CalculateSize() {
       int size = 0;
       if (Service.Length != 0) {
@@ -119,6 +130,7 @@
       return size;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void MergeFrom(HealthCheckRequest other) {
       if (other == null) {
         return;
@@ -128,6 +140,7 @@
       }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void MergeFrom(pb::CodedInputStream input) {
       uint tag;
       while ((tag = input.ReadTag()) != 0) {
@@ -145,29 +158,34 @@
 
   }
 
-  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
   public sealed partial class HealthCheckResponse : pb::IMessage<HealthCheckResponse> {
     private static readonly pb::MessageParser<HealthCheckResponse> _parser = new pb::MessageParser<HealthCheckResponse>(() => new HealthCheckResponse());
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pb::MessageParser<HealthCheckResponse> Parser { get { return _parser; } }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pbr::MessageDescriptor Descriptor {
       get { return global::Grpc.Health.V1.HealthReflection.Descriptor.MessageTypes[1]; }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     pbr::MessageDescriptor pb::IMessage.Descriptor {
       get { return Descriptor; }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public HealthCheckResponse() {
       OnConstruction();
     }
 
     partial void OnConstruction();
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public HealthCheckResponse(HealthCheckResponse other) : this() {
       status_ = other.status_;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public HealthCheckResponse Clone() {
       return new HealthCheckResponse(this);
     }
@@ -175,6 +193,7 @@
     /// <summary>Field number for the "status" field.</summary>
     public const int StatusFieldNumber = 1;
     private global::Grpc.Health.V1.HealthCheckResponse.Types.ServingStatus status_ = 0;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public global::Grpc.Health.V1.HealthCheckResponse.Types.ServingStatus Status {
       get { return status_; }
       set {
@@ -182,10 +201,12 @@
       }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override bool Equals(object other) {
       return Equals(other as HealthCheckResponse);
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public bool Equals(HealthCheckResponse other) {
       if (ReferenceEquals(other, null)) {
         return false;
@@ -197,16 +218,19 @@
       return true;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override int GetHashCode() {
       int hash = 1;
       if (Status != 0) hash ^= Status.GetHashCode();
       return hash;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override string ToString() {
       return pb::JsonFormatter.ToDiagnosticString(this);
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void WriteTo(pb::CodedOutputStream output) {
       if (Status != 0) {
         output.WriteRawTag(8);
@@ -214,6 +238,7 @@
       }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public int CalculateSize() {
       int size = 0;
       if (Status != 0) {
@@ -222,6 +247,7 @@
       return size;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void MergeFrom(HealthCheckResponse other) {
       if (other == null) {
         return;
@@ -231,6 +257,7 @@
       }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void MergeFrom(pb::CodedInputStream input) {
       uint tag;
       while ((tag = input.ReadTag()) != 0) {
@@ -248,7 +275,7 @@
 
     #region Nested types
     /// <summary>Container for nested types declared in the HealthCheckResponse message type.</summary>
-    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static partial class Types {
       public enum ServingStatus {
         [pbr::OriginalName("UNKNOWN")] Unknown = 0,
diff --git a/src/csharp/Grpc.HealthCheck/HealthGrpc.cs b/src/csharp/Grpc.HealthCheck/HealthGrpc.cs
index 43eea0f..b2a35a7 100644
--- a/src/csharp/Grpc.HealthCheck/HealthGrpc.cs
+++ b/src/csharp/Grpc.HealthCheck/HealthGrpc.cs
@@ -107,6 +107,7 @@
       {
         return CallInvoker.AsyncUnaryCall(__Method_Check, null, options, request);
       }
+      /// <summary>Creates a new instance of client from given <c>ClientBaseConfiguration</c>.</summary>
       protected override HealthClient NewInstance(ClientBaseConfiguration configuration)
       {
         return new HealthClient(configuration);
diff --git a/src/csharp/Grpc.IntegrationTesting/Control.cs b/src/csharp/Grpc.IntegrationTesting/Control.cs
index 412f800..7928b51 100644
--- a/src/csharp/Grpc.IntegrationTesting/Control.cs
+++ b/src/csharp/Grpc.IntegrationTesting/Control.cs
@@ -10,7 +10,6 @@
 namespace Grpc.Testing {
 
   /// <summary>Holder for reflection information generated from src/proto/grpc/testing/control.proto</summary>
-  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
   public static partial class ControlReflection {
 
     #region Descriptor
@@ -71,18 +70,19 @@
             "ASgBEhoKEmNsaWVudF9zeXN0ZW1fdGltZRgFIAEoARIYChBjbGllbnRfdXNl",
             "cl90aW1lGAYgASgBEhIKCmxhdGVuY3lfNTAYByABKAESEgoKbGF0ZW5jeV85",
             "MBgIIAEoARISCgpsYXRlbmN5Xzk1GAkgASgBEhIKCmxhdGVuY3lfOTkYCiAB",
-            "KAESEwoLbGF0ZW5jeV85OTkYCyABKAEimAIKDlNjZW5hcmlvUmVzdWx0EigK",
+            "KAESEwoLbGF0ZW5jeV85OTkYCyABKAEiyAIKDlNjZW5hcmlvUmVzdWx0EigK",
             "CHNjZW5hcmlvGAEgASgLMhYuZ3JwYy50ZXN0aW5nLlNjZW5hcmlvEi4KCWxh",
             "dGVuY2llcxgCIAEoCzIbLmdycGMudGVzdGluZy5IaXN0b2dyYW1EYXRhEi8K",
             "DGNsaWVudF9zdGF0cxgDIAMoCzIZLmdycGMudGVzdGluZy5DbGllbnRTdGF0",
             "cxIvCgxzZXJ2ZXJfc3RhdHMYBCADKAsyGS5ncnBjLnRlc3RpbmcuU2VydmVy",
             "U3RhdHMSFAoMc2VydmVyX2NvcmVzGAUgAygFEjQKB3N1bW1hcnkYBiABKAsy",
-            "Iy5ncnBjLnRlc3RpbmcuU2NlbmFyaW9SZXN1bHRTdW1tYXJ5KkEKCkNsaWVu",
-            "dFR5cGUSDwoLU1lOQ19DTElFTlQQABIQCgxBU1lOQ19DTElFTlQQARIQCgxP",
-            "VEhFUl9DTElFTlQQAipbCgpTZXJ2ZXJUeXBlEg8KC1NZTkNfU0VSVkVSEAAS",
-            "EAoMQVNZTkNfU0VSVkVSEAESGAoUQVNZTkNfR0VORVJJQ19TRVJWRVIQAhIQ",
-            "CgxPVEhFUl9TRVJWRVIQAyojCgdScGNUeXBlEgkKBVVOQVJZEAASDQoJU1RS",
-            "RUFNSU5HEAFiBnByb3RvMw=="));
+            "Iy5ncnBjLnRlc3RpbmcuU2NlbmFyaW9SZXN1bHRTdW1tYXJ5EhYKDmNsaWVu",
+            "dF9zdWNjZXNzGAcgAygIEhYKDnNlcnZlcl9zdWNjZXNzGAggAygIKkEKCkNs",
+            "aWVudFR5cGUSDwoLU1lOQ19DTElFTlQQABIQCgxBU1lOQ19DTElFTlQQARIQ",
+            "CgxPVEhFUl9DTElFTlQQAipbCgpTZXJ2ZXJUeXBlEg8KC1NZTkNfU0VSVkVS",
+            "EAASEAoMQVNZTkNfU0VSVkVSEAESGAoUQVNZTkNfR0VORVJJQ19TRVJWRVIQ",
+            "AhIQCgxPVEhFUl9TRVJWRVIQAyojCgdScGNUeXBlEgkKBVVOQVJZEAASDQoJ",
+            "U1RSRUFNSU5HEAFiBnByb3RvMw=="));
       descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
           new pbr::FileDescriptor[] { global::Grpc.Testing.PayloadsReflection.Descriptor, global::Grpc.Testing.StatsReflection.Descriptor, },
           new pbr::GeneratedClrTypeInfo(new[] {typeof(global::Grpc.Testing.ClientType), typeof(global::Grpc.Testing.ServerType), typeof(global::Grpc.Testing.RpcType), }, new pbr::GeneratedClrTypeInfo[] {
@@ -103,7 +103,7 @@
             new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Testing.Scenario), global::Grpc.Testing.Scenario.Parser, new[]{ "Name", "ClientConfig", "NumClients", "ServerConfig", "NumServers", "WarmupSeconds", "BenchmarkSeconds", "SpawnLocalWorkerCount" }, null, null, null),
             new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Testing.Scenarios), global::Grpc.Testing.Scenarios.Parser, new[]{ "Scenarios_" }, null, null, null),
             new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Testing.ScenarioResultSummary), global::Grpc.Testing.ScenarioResultSummary.Parser, new[]{ "Qps", "QpsPerServerCore", "ServerSystemTime", "ServerUserTime", "ClientSystemTime", "ClientUserTime", "Latency50", "Latency90", "Latency95", "Latency99", "Latency999" }, null, null, null),
-            new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Testing.ScenarioResult), global::Grpc.Testing.ScenarioResult.Parser, new[]{ "Scenario", "Latencies", "ClientStats", "ServerStats", "ServerCores", "Summary" }, null, null, null)
+            new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Testing.ScenarioResult), global::Grpc.Testing.ScenarioResult.Parser, new[]{ "Scenario", "Latencies", "ClientStats", "ServerStats", "ServerCores", "Summary", "ClientSuccess", "ServerSuccess" }, null, null, null)
           }));
     }
     #endregion
@@ -145,29 +145,34 @@
   ///  Parameters of poisson process distribution, which is a good representation
   ///  of activity coming in from independent identical stationary sources.
   /// </summary>
-  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
   public sealed partial class PoissonParams : pb::IMessage<PoissonParams> {
     private static readonly pb::MessageParser<PoissonParams> _parser = new pb::MessageParser<PoissonParams>(() => new PoissonParams());
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pb::MessageParser<PoissonParams> Parser { get { return _parser; } }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pbr::MessageDescriptor Descriptor {
       get { return global::Grpc.Testing.ControlReflection.Descriptor.MessageTypes[0]; }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     pbr::MessageDescriptor pb::IMessage.Descriptor {
       get { return Descriptor; }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public PoissonParams() {
       OnConstruction();
     }
 
     partial void OnConstruction();
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public PoissonParams(PoissonParams other) : this() {
       offeredLoad_ = other.offeredLoad_;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public PoissonParams Clone() {
       return new PoissonParams(this);
     }
@@ -178,6 +183,7 @@
     /// <summary>
     ///  The rate of arrivals (a.k.a. lambda parameter of the exp distribution).
     /// </summary>
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public double OfferedLoad {
       get { return offeredLoad_; }
       set {
@@ -185,10 +191,12 @@
       }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override bool Equals(object other) {
       return Equals(other as PoissonParams);
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public bool Equals(PoissonParams other) {
       if (ReferenceEquals(other, null)) {
         return false;
@@ -200,16 +208,19 @@
       return true;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override int GetHashCode() {
       int hash = 1;
       if (OfferedLoad != 0D) hash ^= OfferedLoad.GetHashCode();
       return hash;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override string ToString() {
       return pb::JsonFormatter.ToDiagnosticString(this);
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void WriteTo(pb::CodedOutputStream output) {
       if (OfferedLoad != 0D) {
         output.WriteRawTag(9);
@@ -217,6 +228,7 @@
       }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public int CalculateSize() {
       int size = 0;
       if (OfferedLoad != 0D) {
@@ -225,6 +237,7 @@
       return size;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void MergeFrom(PoissonParams other) {
       if (other == null) {
         return;
@@ -234,6 +247,7 @@
       }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void MergeFrom(pb::CodedInputStream input) {
       uint tag;
       while ((tag = input.ReadTag()) != 0) {
@@ -255,36 +269,43 @@
   ///  Once an RPC finishes, immediately start a new one.
   ///  No configuration parameters needed.
   /// </summary>
-  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
   public sealed partial class ClosedLoopParams : pb::IMessage<ClosedLoopParams> {
     private static readonly pb::MessageParser<ClosedLoopParams> _parser = new pb::MessageParser<ClosedLoopParams>(() => new ClosedLoopParams());
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pb::MessageParser<ClosedLoopParams> Parser { get { return _parser; } }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pbr::MessageDescriptor Descriptor {
       get { return global::Grpc.Testing.ControlReflection.Descriptor.MessageTypes[1]; }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     pbr::MessageDescriptor pb::IMessage.Descriptor {
       get { return Descriptor; }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public ClosedLoopParams() {
       OnConstruction();
     }
 
     partial void OnConstruction();
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public ClosedLoopParams(ClosedLoopParams other) : this() {
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public ClosedLoopParams Clone() {
       return new ClosedLoopParams(this);
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override bool Equals(object other) {
       return Equals(other as ClosedLoopParams);
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public bool Equals(ClosedLoopParams other) {
       if (ReferenceEquals(other, null)) {
         return false;
@@ -295,29 +316,35 @@
       return true;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override int GetHashCode() {
       int hash = 1;
       return hash;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override string ToString() {
       return pb::JsonFormatter.ToDiagnosticString(this);
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void WriteTo(pb::CodedOutputStream output) {
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public int CalculateSize() {
       int size = 0;
       return size;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void MergeFrom(ClosedLoopParams other) {
       if (other == null) {
         return;
       }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void MergeFrom(pb::CodedInputStream input) {
       uint tag;
       while ((tag = input.ReadTag()) != 0) {
@@ -331,25 +358,29 @@
 
   }
 
-  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
   public sealed partial class LoadParams : pb::IMessage<LoadParams> {
     private static readonly pb::MessageParser<LoadParams> _parser = new pb::MessageParser<LoadParams>(() => new LoadParams());
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pb::MessageParser<LoadParams> Parser { get { return _parser; } }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pbr::MessageDescriptor Descriptor {
       get { return global::Grpc.Testing.ControlReflection.Descriptor.MessageTypes[2]; }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     pbr::MessageDescriptor pb::IMessage.Descriptor {
       get { return Descriptor; }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public LoadParams() {
       OnConstruction();
     }
 
     partial void OnConstruction();
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public LoadParams(LoadParams other) : this() {
       switch (other.LoadCase) {
         case LoadOneofCase.ClosedLoop:
@@ -362,12 +393,14 @@
 
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public LoadParams Clone() {
       return new LoadParams(this);
     }
 
     /// <summary>Field number for the "closed_loop" field.</summary>
     public const int ClosedLoopFieldNumber = 1;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public global::Grpc.Testing.ClosedLoopParams ClosedLoop {
       get { return loadCase_ == LoadOneofCase.ClosedLoop ? (global::Grpc.Testing.ClosedLoopParams) load_ : null; }
       set {
@@ -378,6 +411,7 @@
 
     /// <summary>Field number for the "poisson" field.</summary>
     public const int PoissonFieldNumber = 2;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public global::Grpc.Testing.PoissonParams Poisson {
       get { return loadCase_ == LoadOneofCase.Poisson ? (global::Grpc.Testing.PoissonParams) load_ : null; }
       set {
@@ -394,19 +428,23 @@
       Poisson = 2,
     }
     private LoadOneofCase loadCase_ = LoadOneofCase.None;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public LoadOneofCase LoadCase {
       get { return loadCase_; }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void ClearLoad() {
       loadCase_ = LoadOneofCase.None;
       load_ = null;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override bool Equals(object other) {
       return Equals(other as LoadParams);
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public bool Equals(LoadParams other) {
       if (ReferenceEquals(other, null)) {
         return false;
@@ -420,6 +458,7 @@
       return true;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override int GetHashCode() {
       int hash = 1;
       if (loadCase_ == LoadOneofCase.ClosedLoop) hash ^= ClosedLoop.GetHashCode();
@@ -428,10 +467,12 @@
       return hash;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override string ToString() {
       return pb::JsonFormatter.ToDiagnosticString(this);
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void WriteTo(pb::CodedOutputStream output) {
       if (loadCase_ == LoadOneofCase.ClosedLoop) {
         output.WriteRawTag(10);
@@ -443,6 +484,7 @@
       }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public int CalculateSize() {
       int size = 0;
       if (loadCase_ == LoadOneofCase.ClosedLoop) {
@@ -454,6 +496,7 @@
       return size;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void MergeFrom(LoadParams other) {
       if (other == null) {
         return;
@@ -469,6 +512,7 @@
 
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void MergeFrom(pb::CodedInputStream input) {
       uint tag;
       while ((tag = input.ReadTag()) != 0) {
@@ -503,30 +547,35 @@
   /// <summary>
   ///  presence of SecurityParams implies use of TLS
   /// </summary>
-  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
   public sealed partial class SecurityParams : pb::IMessage<SecurityParams> {
     private static readonly pb::MessageParser<SecurityParams> _parser = new pb::MessageParser<SecurityParams>(() => new SecurityParams());
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pb::MessageParser<SecurityParams> Parser { get { return _parser; } }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pbr::MessageDescriptor Descriptor {
       get { return global::Grpc.Testing.ControlReflection.Descriptor.MessageTypes[3]; }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     pbr::MessageDescriptor pb::IMessage.Descriptor {
       get { return Descriptor; }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public SecurityParams() {
       OnConstruction();
     }
 
     partial void OnConstruction();
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public SecurityParams(SecurityParams other) : this() {
       useTestCa_ = other.useTestCa_;
       serverHostOverride_ = other.serverHostOverride_;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public SecurityParams Clone() {
       return new SecurityParams(this);
     }
@@ -534,6 +583,7 @@
     /// <summary>Field number for the "use_test_ca" field.</summary>
     public const int UseTestCaFieldNumber = 1;
     private bool useTestCa_;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public bool UseTestCa {
       get { return useTestCa_; }
       set {
@@ -544,6 +594,7 @@
     /// <summary>Field number for the "server_host_override" field.</summary>
     public const int ServerHostOverrideFieldNumber = 2;
     private string serverHostOverride_ = "";
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public string ServerHostOverride {
       get { return serverHostOverride_; }
       set {
@@ -551,10 +602,12 @@
       }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override bool Equals(object other) {
       return Equals(other as SecurityParams);
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public bool Equals(SecurityParams other) {
       if (ReferenceEquals(other, null)) {
         return false;
@@ -567,6 +620,7 @@
       return true;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override int GetHashCode() {
       int hash = 1;
       if (UseTestCa != false) hash ^= UseTestCa.GetHashCode();
@@ -574,10 +628,12 @@
       return hash;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override string ToString() {
       return pb::JsonFormatter.ToDiagnosticString(this);
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void WriteTo(pb::CodedOutputStream output) {
       if (UseTestCa != false) {
         output.WriteRawTag(8);
@@ -589,6 +645,7 @@
       }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public int CalculateSize() {
       int size = 0;
       if (UseTestCa != false) {
@@ -600,6 +657,7 @@
       return size;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void MergeFrom(SecurityParams other) {
       if (other == null) {
         return;
@@ -612,6 +670,7 @@
       }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void MergeFrom(pb::CodedInputStream input) {
       uint tag;
       while ((tag = input.ReadTag()) != 0) {
@@ -633,25 +692,29 @@
 
   }
 
-  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
   public sealed partial class ClientConfig : pb::IMessage<ClientConfig> {
     private static readonly pb::MessageParser<ClientConfig> _parser = new pb::MessageParser<ClientConfig>(() => new ClientConfig());
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pb::MessageParser<ClientConfig> Parser { get { return _parser; } }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pbr::MessageDescriptor Descriptor {
       get { return global::Grpc.Testing.ControlReflection.Descriptor.MessageTypes[4]; }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     pbr::MessageDescriptor pb::IMessage.Descriptor {
       get { return Descriptor; }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public ClientConfig() {
       OnConstruction();
     }
 
     partial void OnConstruction();
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public ClientConfig(ClientConfig other) : this() {
       serverTargets_ = other.serverTargets_.Clone();
       clientType_ = other.clientType_;
@@ -668,6 +731,7 @@
       otherClientApi_ = other.otherClientApi_;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public ClientConfig Clone() {
       return new ClientConfig(this);
     }
@@ -680,6 +744,7 @@
     /// <summary>
     ///  List of targets to connect to. At least one target needs to be specified.
     /// </summary>
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public pbc::RepeatedField<string> ServerTargets {
       get { return serverTargets_; }
     }
@@ -687,6 +752,7 @@
     /// <summary>Field number for the "client_type" field.</summary>
     public const int ClientTypeFieldNumber = 2;
     private global::Grpc.Testing.ClientType clientType_ = 0;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public global::Grpc.Testing.ClientType ClientType {
       get { return clientType_; }
       set {
@@ -697,6 +763,7 @@
     /// <summary>Field number for the "security_params" field.</summary>
     public const int SecurityParamsFieldNumber = 3;
     private global::Grpc.Testing.SecurityParams securityParams_;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public global::Grpc.Testing.SecurityParams SecurityParams {
       get { return securityParams_; }
       set {
@@ -711,6 +778,7 @@
     ///  How many concurrent RPCs to start for each channel.
     ///  For synchronous client, use a separate thread for each outstanding RPC.
     /// </summary>
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public int OutstandingRpcsPerChannel {
       get { return outstandingRpcsPerChannel_; }
       set {
@@ -725,6 +793,7 @@
     ///  Number of independent client channels to create.
     ///  i-th channel will connect to server_target[i % server_targets.size()]
     /// </summary>
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public int ClientChannels {
       get { return clientChannels_; }
       set {
@@ -738,6 +807,7 @@
     /// <summary>
     ///  Only for async client. Number of threads to use to start/manage RPCs.
     /// </summary>
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public int AsyncClientThreads {
       get { return asyncClientThreads_; }
       set {
@@ -748,6 +818,7 @@
     /// <summary>Field number for the "rpc_type" field.</summary>
     public const int RpcTypeFieldNumber = 8;
     private global::Grpc.Testing.RpcType rpcType_ = 0;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public global::Grpc.Testing.RpcType RpcType {
       get { return rpcType_; }
       set {
@@ -761,6 +832,7 @@
     /// <summary>
     ///  The requested load for the entire client (aggregated over all the threads).
     /// </summary>
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public global::Grpc.Testing.LoadParams LoadParams {
       get { return loadParams_; }
       set {
@@ -771,6 +843,7 @@
     /// <summary>Field number for the "payload_config" field.</summary>
     public const int PayloadConfigFieldNumber = 11;
     private global::Grpc.Testing.PayloadConfig payloadConfig_;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public global::Grpc.Testing.PayloadConfig PayloadConfig {
       get { return payloadConfig_; }
       set {
@@ -781,6 +854,7 @@
     /// <summary>Field number for the "histogram_params" field.</summary>
     public const int HistogramParamsFieldNumber = 12;
     private global::Grpc.Testing.HistogramParams histogramParams_;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public global::Grpc.Testing.HistogramParams HistogramParams {
       get { return histogramParams_; }
       set {
@@ -796,6 +870,7 @@
     /// <summary>
     ///  Specify the cores we should run the client on, if desired
     /// </summary>
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public pbc::RepeatedField<int> CoreList {
       get { return coreList_; }
     }
@@ -803,6 +878,7 @@
     /// <summary>Field number for the "core_limit" field.</summary>
     public const int CoreLimitFieldNumber = 14;
     private int coreLimit_;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public int CoreLimit {
       get { return coreLimit_; }
       set {
@@ -816,6 +892,7 @@
     /// <summary>
     ///  If we use an OTHER_CLIENT client_type, this string gives more detail
     /// </summary>
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public string OtherClientApi {
       get { return otherClientApi_; }
       set {
@@ -823,10 +900,12 @@
       }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override bool Equals(object other) {
       return Equals(other as ClientConfig);
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public bool Equals(ClientConfig other) {
       if (ReferenceEquals(other, null)) {
         return false;
@@ -850,6 +929,7 @@
       return true;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override int GetHashCode() {
       int hash = 1;
       hash ^= serverTargets_.GetHashCode();
@@ -868,10 +948,12 @@
       return hash;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override string ToString() {
       return pb::JsonFormatter.ToDiagnosticString(this);
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void WriteTo(pb::CodedOutputStream output) {
       serverTargets_.WriteTo(output, _repeated_serverTargets_codec);
       if (ClientType != 0) {
@@ -921,6 +1003,7 @@
       }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public int CalculateSize() {
       int size = 0;
       size += serverTargets_.CalculateSize(_repeated_serverTargets_codec);
@@ -961,6 +1044,7 @@
       return size;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void MergeFrom(ClientConfig other) {
       if (other == null) {
         return;
@@ -1014,6 +1098,7 @@
       }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void MergeFrom(pb::CodedInputStream input) {
       uint tag;
       while ((tag = input.ReadTag()) != 0) {
@@ -1092,29 +1177,34 @@
 
   }
 
-  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
   public sealed partial class ClientStatus : pb::IMessage<ClientStatus> {
     private static readonly pb::MessageParser<ClientStatus> _parser = new pb::MessageParser<ClientStatus>(() => new ClientStatus());
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pb::MessageParser<ClientStatus> Parser { get { return _parser; } }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pbr::MessageDescriptor Descriptor {
       get { return global::Grpc.Testing.ControlReflection.Descriptor.MessageTypes[5]; }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     pbr::MessageDescriptor pb::IMessage.Descriptor {
       get { return Descriptor; }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public ClientStatus() {
       OnConstruction();
     }
 
     partial void OnConstruction();
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public ClientStatus(ClientStatus other) : this() {
       Stats = other.stats_ != null ? other.Stats.Clone() : null;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public ClientStatus Clone() {
       return new ClientStatus(this);
     }
@@ -1122,6 +1212,7 @@
     /// <summary>Field number for the "stats" field.</summary>
     public const int StatsFieldNumber = 1;
     private global::Grpc.Testing.ClientStats stats_;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public global::Grpc.Testing.ClientStats Stats {
       get { return stats_; }
       set {
@@ -1129,10 +1220,12 @@
       }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override bool Equals(object other) {
       return Equals(other as ClientStatus);
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public bool Equals(ClientStatus other) {
       if (ReferenceEquals(other, null)) {
         return false;
@@ -1144,16 +1237,19 @@
       return true;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override int GetHashCode() {
       int hash = 1;
       if (stats_ != null) hash ^= Stats.GetHashCode();
       return hash;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override string ToString() {
       return pb::JsonFormatter.ToDiagnosticString(this);
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void WriteTo(pb::CodedOutputStream output) {
       if (stats_ != null) {
         output.WriteRawTag(10);
@@ -1161,6 +1257,7 @@
       }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public int CalculateSize() {
       int size = 0;
       if (stats_ != null) {
@@ -1169,6 +1266,7 @@
       return size;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void MergeFrom(ClientStatus other) {
       if (other == null) {
         return;
@@ -1181,6 +1279,7 @@
       }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void MergeFrom(pb::CodedInputStream input) {
       uint tag;
       while ((tag = input.ReadTag()) != 0) {
@@ -1204,29 +1303,34 @@
   /// <summary>
   ///  Request current stats
   /// </summary>
-  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
   public sealed partial class Mark : pb::IMessage<Mark> {
     private static readonly pb::MessageParser<Mark> _parser = new pb::MessageParser<Mark>(() => new Mark());
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pb::MessageParser<Mark> Parser { get { return _parser; } }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pbr::MessageDescriptor Descriptor {
       get { return global::Grpc.Testing.ControlReflection.Descriptor.MessageTypes[6]; }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     pbr::MessageDescriptor pb::IMessage.Descriptor {
       get { return Descriptor; }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public Mark() {
       OnConstruction();
     }
 
     partial void OnConstruction();
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public Mark(Mark other) : this() {
       reset_ = other.reset_;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public Mark Clone() {
       return new Mark(this);
     }
@@ -1237,6 +1341,7 @@
     /// <summary>
     ///  if true, the stats will be reset after taking their snapshot.
     /// </summary>
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public bool Reset {
       get { return reset_; }
       set {
@@ -1244,10 +1349,12 @@
       }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override bool Equals(object other) {
       return Equals(other as Mark);
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public bool Equals(Mark other) {
       if (ReferenceEquals(other, null)) {
         return false;
@@ -1259,16 +1366,19 @@
       return true;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override int GetHashCode() {
       int hash = 1;
       if (Reset != false) hash ^= Reset.GetHashCode();
       return hash;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override string ToString() {
       return pb::JsonFormatter.ToDiagnosticString(this);
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void WriteTo(pb::CodedOutputStream output) {
       if (Reset != false) {
         output.WriteRawTag(8);
@@ -1276,6 +1386,7 @@
       }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public int CalculateSize() {
       int size = 0;
       if (Reset != false) {
@@ -1284,6 +1395,7 @@
       return size;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void MergeFrom(Mark other) {
       if (other == null) {
         return;
@@ -1293,6 +1405,7 @@
       }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void MergeFrom(pb::CodedInputStream input) {
       uint tag;
       while ((tag = input.ReadTag()) != 0) {
@@ -1310,25 +1423,29 @@
 
   }
 
-  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
   public sealed partial class ClientArgs : pb::IMessage<ClientArgs> {
     private static readonly pb::MessageParser<ClientArgs> _parser = new pb::MessageParser<ClientArgs>(() => new ClientArgs());
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pb::MessageParser<ClientArgs> Parser { get { return _parser; } }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pbr::MessageDescriptor Descriptor {
       get { return global::Grpc.Testing.ControlReflection.Descriptor.MessageTypes[7]; }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     pbr::MessageDescriptor pb::IMessage.Descriptor {
       get { return Descriptor; }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public ClientArgs() {
       OnConstruction();
     }
 
     partial void OnConstruction();
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public ClientArgs(ClientArgs other) : this() {
       switch (other.ArgtypeCase) {
         case ArgtypeOneofCase.Setup:
@@ -1341,12 +1458,14 @@
 
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public ClientArgs Clone() {
       return new ClientArgs(this);
     }
 
     /// <summary>Field number for the "setup" field.</summary>
     public const int SetupFieldNumber = 1;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public global::Grpc.Testing.ClientConfig Setup {
       get { return argtypeCase_ == ArgtypeOneofCase.Setup ? (global::Grpc.Testing.ClientConfig) argtype_ : null; }
       set {
@@ -1357,6 +1476,7 @@
 
     /// <summary>Field number for the "mark" field.</summary>
     public const int MarkFieldNumber = 2;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public global::Grpc.Testing.Mark Mark {
       get { return argtypeCase_ == ArgtypeOneofCase.Mark ? (global::Grpc.Testing.Mark) argtype_ : null; }
       set {
@@ -1373,19 +1493,23 @@
       Mark = 2,
     }
     private ArgtypeOneofCase argtypeCase_ = ArgtypeOneofCase.None;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public ArgtypeOneofCase ArgtypeCase {
       get { return argtypeCase_; }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void ClearArgtype() {
       argtypeCase_ = ArgtypeOneofCase.None;
       argtype_ = null;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override bool Equals(object other) {
       return Equals(other as ClientArgs);
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public bool Equals(ClientArgs other) {
       if (ReferenceEquals(other, null)) {
         return false;
@@ -1399,6 +1523,7 @@
       return true;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override int GetHashCode() {
       int hash = 1;
       if (argtypeCase_ == ArgtypeOneofCase.Setup) hash ^= Setup.GetHashCode();
@@ -1407,10 +1532,12 @@
       return hash;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override string ToString() {
       return pb::JsonFormatter.ToDiagnosticString(this);
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void WriteTo(pb::CodedOutputStream output) {
       if (argtypeCase_ == ArgtypeOneofCase.Setup) {
         output.WriteRawTag(10);
@@ -1422,6 +1549,7 @@
       }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public int CalculateSize() {
       int size = 0;
       if (argtypeCase_ == ArgtypeOneofCase.Setup) {
@@ -1433,6 +1561,7 @@
       return size;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void MergeFrom(ClientArgs other) {
       if (other == null) {
         return;
@@ -1448,6 +1577,7 @@
 
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void MergeFrom(pb::CodedInputStream input) {
       uint tag;
       while ((tag = input.ReadTag()) != 0) {
@@ -1479,25 +1609,29 @@
 
   }
 
-  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
   public sealed partial class ServerConfig : pb::IMessage<ServerConfig> {
     private static readonly pb::MessageParser<ServerConfig> _parser = new pb::MessageParser<ServerConfig>(() => new ServerConfig());
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pb::MessageParser<ServerConfig> Parser { get { return _parser; } }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pbr::MessageDescriptor Descriptor {
       get { return global::Grpc.Testing.ControlReflection.Descriptor.MessageTypes[8]; }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     pbr::MessageDescriptor pb::IMessage.Descriptor {
       get { return Descriptor; }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public ServerConfig() {
       OnConstruction();
     }
 
     partial void OnConstruction();
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public ServerConfig(ServerConfig other) : this() {
       serverType_ = other.serverType_;
       SecurityParams = other.securityParams_ != null ? other.SecurityParams.Clone() : null;
@@ -1509,6 +1643,7 @@
       otherServerApi_ = other.otherServerApi_;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public ServerConfig Clone() {
       return new ServerConfig(this);
     }
@@ -1516,6 +1651,7 @@
     /// <summary>Field number for the "server_type" field.</summary>
     public const int ServerTypeFieldNumber = 1;
     private global::Grpc.Testing.ServerType serverType_ = 0;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public global::Grpc.Testing.ServerType ServerType {
       get { return serverType_; }
       set {
@@ -1526,6 +1662,7 @@
     /// <summary>Field number for the "security_params" field.</summary>
     public const int SecurityParamsFieldNumber = 2;
     private global::Grpc.Testing.SecurityParams securityParams_;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public global::Grpc.Testing.SecurityParams SecurityParams {
       get { return securityParams_; }
       set {
@@ -1539,6 +1676,7 @@
     /// <summary>
     ///  Port on which to listen. Zero means pick unused port.
     /// </summary>
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public int Port {
       get { return port_; }
       set {
@@ -1552,6 +1690,7 @@
     /// <summary>
     ///  Only for async server. Number of threads used to serve the requests.
     /// </summary>
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public int AsyncServerThreads {
       get { return asyncServerThreads_; }
       set {
@@ -1565,6 +1704,7 @@
     /// <summary>
     ///  Specify the number of cores to limit server to, if desired
     /// </summary>
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public int CoreLimit {
       get { return coreLimit_; }
       set {
@@ -1578,6 +1718,7 @@
     /// <summary>
     ///  payload config, used in generic server
     /// </summary>
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public global::Grpc.Testing.PayloadConfig PayloadConfig {
       get { return payloadConfig_; }
       set {
@@ -1593,6 +1734,7 @@
     /// <summary>
     ///  Specify the cores we should run the server on, if desired
     /// </summary>
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public pbc::RepeatedField<int> CoreList {
       get { return coreList_; }
     }
@@ -1603,6 +1745,7 @@
     /// <summary>
     ///  If we use an OTHER_SERVER client_type, this string gives more detail
     /// </summary>
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public string OtherServerApi {
       get { return otherServerApi_; }
       set {
@@ -1610,10 +1753,12 @@
       }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override bool Equals(object other) {
       return Equals(other as ServerConfig);
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public bool Equals(ServerConfig other) {
       if (ReferenceEquals(other, null)) {
         return false;
@@ -1632,6 +1777,7 @@
       return true;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override int GetHashCode() {
       int hash = 1;
       if (ServerType != 0) hash ^= ServerType.GetHashCode();
@@ -1645,10 +1791,12 @@
       return hash;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override string ToString() {
       return pb::JsonFormatter.ToDiagnosticString(this);
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void WriteTo(pb::CodedOutputStream output) {
       if (ServerType != 0) {
         output.WriteRawTag(8);
@@ -1681,6 +1829,7 @@
       }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public int CalculateSize() {
       int size = 0;
       if (ServerType != 0) {
@@ -1708,6 +1857,7 @@
       return size;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void MergeFrom(ServerConfig other) {
       if (other == null) {
         return;
@@ -1742,6 +1892,7 @@
       }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void MergeFrom(pb::CodedInputStream input) {
       uint tag;
       while ((tag = input.ReadTag()) != 0) {
@@ -1794,25 +1945,29 @@
 
   }
 
-  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
   public sealed partial class ServerArgs : pb::IMessage<ServerArgs> {
     private static readonly pb::MessageParser<ServerArgs> _parser = new pb::MessageParser<ServerArgs>(() => new ServerArgs());
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pb::MessageParser<ServerArgs> Parser { get { return _parser; } }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pbr::MessageDescriptor Descriptor {
       get { return global::Grpc.Testing.ControlReflection.Descriptor.MessageTypes[9]; }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     pbr::MessageDescriptor pb::IMessage.Descriptor {
       get { return Descriptor; }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public ServerArgs() {
       OnConstruction();
     }
 
     partial void OnConstruction();
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public ServerArgs(ServerArgs other) : this() {
       switch (other.ArgtypeCase) {
         case ArgtypeOneofCase.Setup:
@@ -1825,12 +1980,14 @@
 
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public ServerArgs Clone() {
       return new ServerArgs(this);
     }
 
     /// <summary>Field number for the "setup" field.</summary>
     public const int SetupFieldNumber = 1;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public global::Grpc.Testing.ServerConfig Setup {
       get { return argtypeCase_ == ArgtypeOneofCase.Setup ? (global::Grpc.Testing.ServerConfig) argtype_ : null; }
       set {
@@ -1841,6 +1998,7 @@
 
     /// <summary>Field number for the "mark" field.</summary>
     public const int MarkFieldNumber = 2;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public global::Grpc.Testing.Mark Mark {
       get { return argtypeCase_ == ArgtypeOneofCase.Mark ? (global::Grpc.Testing.Mark) argtype_ : null; }
       set {
@@ -1857,19 +2015,23 @@
       Mark = 2,
     }
     private ArgtypeOneofCase argtypeCase_ = ArgtypeOneofCase.None;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public ArgtypeOneofCase ArgtypeCase {
       get { return argtypeCase_; }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void ClearArgtype() {
       argtypeCase_ = ArgtypeOneofCase.None;
       argtype_ = null;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override bool Equals(object other) {
       return Equals(other as ServerArgs);
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public bool Equals(ServerArgs other) {
       if (ReferenceEquals(other, null)) {
         return false;
@@ -1883,6 +2045,7 @@
       return true;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override int GetHashCode() {
       int hash = 1;
       if (argtypeCase_ == ArgtypeOneofCase.Setup) hash ^= Setup.GetHashCode();
@@ -1891,10 +2054,12 @@
       return hash;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override string ToString() {
       return pb::JsonFormatter.ToDiagnosticString(this);
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void WriteTo(pb::CodedOutputStream output) {
       if (argtypeCase_ == ArgtypeOneofCase.Setup) {
         output.WriteRawTag(10);
@@ -1906,6 +2071,7 @@
       }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public int CalculateSize() {
       int size = 0;
       if (argtypeCase_ == ArgtypeOneofCase.Setup) {
@@ -1917,6 +2083,7 @@
       return size;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void MergeFrom(ServerArgs other) {
       if (other == null) {
         return;
@@ -1932,6 +2099,7 @@
 
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void MergeFrom(pb::CodedInputStream input) {
       uint tag;
       while ((tag = input.ReadTag()) != 0) {
@@ -1963,31 +2131,36 @@
 
   }
 
-  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
   public sealed partial class ServerStatus : pb::IMessage<ServerStatus> {
     private static readonly pb::MessageParser<ServerStatus> _parser = new pb::MessageParser<ServerStatus>(() => new ServerStatus());
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pb::MessageParser<ServerStatus> Parser { get { return _parser; } }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pbr::MessageDescriptor Descriptor {
       get { return global::Grpc.Testing.ControlReflection.Descriptor.MessageTypes[10]; }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     pbr::MessageDescriptor pb::IMessage.Descriptor {
       get { return Descriptor; }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public ServerStatus() {
       OnConstruction();
     }
 
     partial void OnConstruction();
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public ServerStatus(ServerStatus other) : this() {
       Stats = other.stats_ != null ? other.Stats.Clone() : null;
       port_ = other.port_;
       cores_ = other.cores_;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public ServerStatus Clone() {
       return new ServerStatus(this);
     }
@@ -1995,6 +2168,7 @@
     /// <summary>Field number for the "stats" field.</summary>
     public const int StatsFieldNumber = 1;
     private global::Grpc.Testing.ServerStats stats_;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public global::Grpc.Testing.ServerStats Stats {
       get { return stats_; }
       set {
@@ -2008,6 +2182,7 @@
     /// <summary>
     ///  the port bound by the server
     /// </summary>
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public int Port {
       get { return port_; }
       set {
@@ -2021,6 +2196,7 @@
     /// <summary>
     ///  Number of cores available to the server
     /// </summary>
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public int Cores {
       get { return cores_; }
       set {
@@ -2028,10 +2204,12 @@
       }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override bool Equals(object other) {
       return Equals(other as ServerStatus);
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public bool Equals(ServerStatus other) {
       if (ReferenceEquals(other, null)) {
         return false;
@@ -2045,6 +2223,7 @@
       return true;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override int GetHashCode() {
       int hash = 1;
       if (stats_ != null) hash ^= Stats.GetHashCode();
@@ -2053,10 +2232,12 @@
       return hash;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override string ToString() {
       return pb::JsonFormatter.ToDiagnosticString(this);
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void WriteTo(pb::CodedOutputStream output) {
       if (stats_ != null) {
         output.WriteRawTag(10);
@@ -2072,6 +2253,7 @@
       }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public int CalculateSize() {
       int size = 0;
       if (stats_ != null) {
@@ -2086,6 +2268,7 @@
       return size;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void MergeFrom(ServerStatus other) {
       if (other == null) {
         return;
@@ -2104,6 +2287,7 @@
       }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void MergeFrom(pb::CodedInputStream input) {
       uint tag;
       while ((tag = input.ReadTag()) != 0) {
@@ -2132,36 +2316,43 @@
 
   }
 
-  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
   public sealed partial class CoreRequest : pb::IMessage<CoreRequest> {
     private static readonly pb::MessageParser<CoreRequest> _parser = new pb::MessageParser<CoreRequest>(() => new CoreRequest());
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pb::MessageParser<CoreRequest> Parser { get { return _parser; } }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pbr::MessageDescriptor Descriptor {
       get { return global::Grpc.Testing.ControlReflection.Descriptor.MessageTypes[11]; }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     pbr::MessageDescriptor pb::IMessage.Descriptor {
       get { return Descriptor; }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public CoreRequest() {
       OnConstruction();
     }
 
     partial void OnConstruction();
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public CoreRequest(CoreRequest other) : this() {
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public CoreRequest Clone() {
       return new CoreRequest(this);
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override bool Equals(object other) {
       return Equals(other as CoreRequest);
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public bool Equals(CoreRequest other) {
       if (ReferenceEquals(other, null)) {
         return false;
@@ -2172,29 +2363,35 @@
       return true;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override int GetHashCode() {
       int hash = 1;
       return hash;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override string ToString() {
       return pb::JsonFormatter.ToDiagnosticString(this);
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void WriteTo(pb::CodedOutputStream output) {
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public int CalculateSize() {
       int size = 0;
       return size;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void MergeFrom(CoreRequest other) {
       if (other == null) {
         return;
       }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void MergeFrom(pb::CodedInputStream input) {
       uint tag;
       while ((tag = input.ReadTag()) != 0) {
@@ -2208,29 +2405,34 @@
 
   }
 
-  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
   public sealed partial class CoreResponse : pb::IMessage<CoreResponse> {
     private static readonly pb::MessageParser<CoreResponse> _parser = new pb::MessageParser<CoreResponse>(() => new CoreResponse());
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pb::MessageParser<CoreResponse> Parser { get { return _parser; } }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pbr::MessageDescriptor Descriptor {
       get { return global::Grpc.Testing.ControlReflection.Descriptor.MessageTypes[12]; }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     pbr::MessageDescriptor pb::IMessage.Descriptor {
       get { return Descriptor; }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public CoreResponse() {
       OnConstruction();
     }
 
     partial void OnConstruction();
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public CoreResponse(CoreResponse other) : this() {
       cores_ = other.cores_;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public CoreResponse Clone() {
       return new CoreResponse(this);
     }
@@ -2241,6 +2443,7 @@
     /// <summary>
     ///  Number of cores available on the server
     /// </summary>
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public int Cores {
       get { return cores_; }
       set {
@@ -2248,10 +2451,12 @@
       }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override bool Equals(object other) {
       return Equals(other as CoreResponse);
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public bool Equals(CoreResponse other) {
       if (ReferenceEquals(other, null)) {
         return false;
@@ -2263,16 +2468,19 @@
       return true;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override int GetHashCode() {
       int hash = 1;
       if (Cores != 0) hash ^= Cores.GetHashCode();
       return hash;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override string ToString() {
       return pb::JsonFormatter.ToDiagnosticString(this);
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void WriteTo(pb::CodedOutputStream output) {
       if (Cores != 0) {
         output.WriteRawTag(8);
@@ -2280,6 +2488,7 @@
       }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public int CalculateSize() {
       int size = 0;
       if (Cores != 0) {
@@ -2288,6 +2497,7 @@
       return size;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void MergeFrom(CoreResponse other) {
       if (other == null) {
         return;
@@ -2297,6 +2507,7 @@
       }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void MergeFrom(pb::CodedInputStream input) {
       uint tag;
       while ((tag = input.ReadTag()) != 0) {
@@ -2314,36 +2525,43 @@
 
   }
 
-  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
   public sealed partial class Void : pb::IMessage<Void> {
     private static readonly pb::MessageParser<Void> _parser = new pb::MessageParser<Void>(() => new Void());
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pb::MessageParser<Void> Parser { get { return _parser; } }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pbr::MessageDescriptor Descriptor {
       get { return global::Grpc.Testing.ControlReflection.Descriptor.MessageTypes[13]; }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     pbr::MessageDescriptor pb::IMessage.Descriptor {
       get { return Descriptor; }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public Void() {
       OnConstruction();
     }
 
     partial void OnConstruction();
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public Void(Void other) : this() {
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public Void Clone() {
       return new Void(this);
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override bool Equals(object other) {
       return Equals(other as Void);
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public bool Equals(Void other) {
       if (ReferenceEquals(other, null)) {
         return false;
@@ -2354,29 +2572,35 @@
       return true;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override int GetHashCode() {
       int hash = 1;
       return hash;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override string ToString() {
       return pb::JsonFormatter.ToDiagnosticString(this);
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void WriteTo(pb::CodedOutputStream output) {
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public int CalculateSize() {
       int size = 0;
       return size;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void MergeFrom(Void other) {
       if (other == null) {
         return;
       }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void MergeFrom(pb::CodedInputStream input) {
       uint tag;
       while ((tag = input.ReadTag()) != 0) {
@@ -2393,25 +2617,29 @@
   /// <summary>
   ///  A single performance scenario: input to qps_json_driver
   /// </summary>
-  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
   public sealed partial class Scenario : pb::IMessage<Scenario> {
     private static readonly pb::MessageParser<Scenario> _parser = new pb::MessageParser<Scenario>(() => new Scenario());
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pb::MessageParser<Scenario> Parser { get { return _parser; } }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pbr::MessageDescriptor Descriptor {
       get { return global::Grpc.Testing.ControlReflection.Descriptor.MessageTypes[14]; }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     pbr::MessageDescriptor pb::IMessage.Descriptor {
       get { return Descriptor; }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public Scenario() {
       OnConstruction();
     }
 
     partial void OnConstruction();
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public Scenario(Scenario other) : this() {
       name_ = other.name_;
       ClientConfig = other.clientConfig_ != null ? other.ClientConfig.Clone() : null;
@@ -2423,6 +2651,7 @@
       spawnLocalWorkerCount_ = other.spawnLocalWorkerCount_;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public Scenario Clone() {
       return new Scenario(this);
     }
@@ -2433,6 +2662,7 @@
     /// <summary>
     ///  Human readable name for this scenario
     /// </summary>
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public string Name {
       get { return name_; }
       set {
@@ -2446,6 +2676,7 @@
     /// <summary>
     ///  Client configuration
     /// </summary>
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public global::Grpc.Testing.ClientConfig ClientConfig {
       get { return clientConfig_; }
       set {
@@ -2459,6 +2690,7 @@
     /// <summary>
     ///  Number of clients to start for the test
     /// </summary>
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public int NumClients {
       get { return numClients_; }
       set {
@@ -2472,6 +2704,7 @@
     /// <summary>
     ///  Server configuration
     /// </summary>
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public global::Grpc.Testing.ServerConfig ServerConfig {
       get { return serverConfig_; }
       set {
@@ -2485,6 +2718,7 @@
     /// <summary>
     ///  Number of servers to start for the test
     /// </summary>
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public int NumServers {
       get { return numServers_; }
       set {
@@ -2498,6 +2732,7 @@
     /// <summary>
     ///  Warmup period, in seconds
     /// </summary>
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public int WarmupSeconds {
       get { return warmupSeconds_; }
       set {
@@ -2511,6 +2746,7 @@
     /// <summary>
     ///  Benchmark time, in seconds
     /// </summary>
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public int BenchmarkSeconds {
       get { return benchmarkSeconds_; }
       set {
@@ -2524,6 +2760,7 @@
     /// <summary>
     ///  Number of workers to spawn locally (usually zero)
     /// </summary>
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public int SpawnLocalWorkerCount {
       get { return spawnLocalWorkerCount_; }
       set {
@@ -2531,10 +2768,12 @@
       }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override bool Equals(object other) {
       return Equals(other as Scenario);
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public bool Equals(Scenario other) {
       if (ReferenceEquals(other, null)) {
         return false;
@@ -2553,6 +2792,7 @@
       return true;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override int GetHashCode() {
       int hash = 1;
       if (Name.Length != 0) hash ^= Name.GetHashCode();
@@ -2566,10 +2806,12 @@
       return hash;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override string ToString() {
       return pb::JsonFormatter.ToDiagnosticString(this);
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void WriteTo(pb::CodedOutputStream output) {
       if (Name.Length != 0) {
         output.WriteRawTag(10);
@@ -2605,6 +2847,7 @@
       }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public int CalculateSize() {
       int size = 0;
       if (Name.Length != 0) {
@@ -2634,6 +2877,7 @@
       return size;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void MergeFrom(Scenario other) {
       if (other == null) {
         return;
@@ -2670,6 +2914,7 @@
       }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void MergeFrom(pb::CodedInputStream input) {
       uint tag;
       while ((tag = input.ReadTag()) != 0) {
@@ -2724,29 +2969,34 @@
   /// <summary>
   ///  A set of scenarios to be run with qps_json_driver
   /// </summary>
-  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
   public sealed partial class Scenarios : pb::IMessage<Scenarios> {
     private static readonly pb::MessageParser<Scenarios> _parser = new pb::MessageParser<Scenarios>(() => new Scenarios());
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pb::MessageParser<Scenarios> Parser { get { return _parser; } }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pbr::MessageDescriptor Descriptor {
       get { return global::Grpc.Testing.ControlReflection.Descriptor.MessageTypes[15]; }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     pbr::MessageDescriptor pb::IMessage.Descriptor {
       get { return Descriptor; }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public Scenarios() {
       OnConstruction();
     }
 
     partial void OnConstruction();
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public Scenarios(Scenarios other) : this() {
       scenarios_ = other.scenarios_.Clone();
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public Scenarios Clone() {
       return new Scenarios(this);
     }
@@ -2756,14 +3006,17 @@
     private static readonly pb::FieldCodec<global::Grpc.Testing.Scenario> _repeated_scenarios_codec
         = pb::FieldCodec.ForMessage(10, global::Grpc.Testing.Scenario.Parser);
     private readonly pbc::RepeatedField<global::Grpc.Testing.Scenario> scenarios_ = new pbc::RepeatedField<global::Grpc.Testing.Scenario>();
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public pbc::RepeatedField<global::Grpc.Testing.Scenario> Scenarios_ {
       get { return scenarios_; }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override bool Equals(object other) {
       return Equals(other as Scenarios);
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public bool Equals(Scenarios other) {
       if (ReferenceEquals(other, null)) {
         return false;
@@ -2775,26 +3028,31 @@
       return true;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override int GetHashCode() {
       int hash = 1;
       hash ^= scenarios_.GetHashCode();
       return hash;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override string ToString() {
       return pb::JsonFormatter.ToDiagnosticString(this);
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void WriteTo(pb::CodedOutputStream output) {
       scenarios_.WriteTo(output, _repeated_scenarios_codec);
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public int CalculateSize() {
       int size = 0;
       size += scenarios_.CalculateSize(_repeated_scenarios_codec);
       return size;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void MergeFrom(Scenarios other) {
       if (other == null) {
         return;
@@ -2802,6 +3060,7 @@
       scenarios_.Add(other.scenarios_);
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void MergeFrom(pb::CodedInputStream input) {
       uint tag;
       while ((tag = input.ReadTag()) != 0) {
@@ -2823,25 +3082,29 @@
   ///  Basic summary that can be computed from ClientStats and ServerStats
   ///  once the scenario has finished.
   /// </summary>
-  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
   public sealed partial class ScenarioResultSummary : pb::IMessage<ScenarioResultSummary> {
     private static readonly pb::MessageParser<ScenarioResultSummary> _parser = new pb::MessageParser<ScenarioResultSummary>(() => new ScenarioResultSummary());
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pb::MessageParser<ScenarioResultSummary> Parser { get { return _parser; } }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pbr::MessageDescriptor Descriptor {
       get { return global::Grpc.Testing.ControlReflection.Descriptor.MessageTypes[16]; }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     pbr::MessageDescriptor pb::IMessage.Descriptor {
       get { return Descriptor; }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public ScenarioResultSummary() {
       OnConstruction();
     }
 
     partial void OnConstruction();
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public ScenarioResultSummary(ScenarioResultSummary other) : this() {
       qps_ = other.qps_;
       qpsPerServerCore_ = other.qpsPerServerCore_;
@@ -2856,6 +3119,7 @@
       latency999_ = other.latency999_;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public ScenarioResultSummary Clone() {
       return new ScenarioResultSummary(this);
     }
@@ -2866,6 +3130,7 @@
     /// <summary>
     ///  Total number of operations per second over all clients.
     /// </summary>
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public double Qps {
       get { return qps_; }
       set {
@@ -2879,6 +3144,7 @@
     /// <summary>
     ///  QPS per one server core.
     /// </summary>
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public double QpsPerServerCore {
       get { return qpsPerServerCore_; }
       set {
@@ -2892,6 +3158,7 @@
     /// <summary>
     ///  server load based on system_time (0.85 => 85%)
     /// </summary>
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public double ServerSystemTime {
       get { return serverSystemTime_; }
       set {
@@ -2905,6 +3172,7 @@
     /// <summary>
     ///  server load based on user_time (0.85 => 85%)
     /// </summary>
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public double ServerUserTime {
       get { return serverUserTime_; }
       set {
@@ -2918,6 +3186,7 @@
     /// <summary>
     ///  client load based on system_time (0.85 => 85%)
     /// </summary>
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public double ClientSystemTime {
       get { return clientSystemTime_; }
       set {
@@ -2931,6 +3200,7 @@
     /// <summary>
     ///  client load based on user_time (0.85 => 85%)
     /// </summary>
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public double ClientUserTime {
       get { return clientUserTime_; }
       set {
@@ -2944,6 +3214,7 @@
     /// <summary>
     ///  X% latency percentiles (in nanoseconds)
     /// </summary>
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public double Latency50 {
       get { return latency50_; }
       set {
@@ -2954,6 +3225,7 @@
     /// <summary>Field number for the "latency_90" field.</summary>
     public const int Latency90FieldNumber = 8;
     private double latency90_;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public double Latency90 {
       get { return latency90_; }
       set {
@@ -2964,6 +3236,7 @@
     /// <summary>Field number for the "latency_95" field.</summary>
     public const int Latency95FieldNumber = 9;
     private double latency95_;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public double Latency95 {
       get { return latency95_; }
       set {
@@ -2974,6 +3247,7 @@
     /// <summary>Field number for the "latency_99" field.</summary>
     public const int Latency99FieldNumber = 10;
     private double latency99_;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public double Latency99 {
       get { return latency99_; }
       set {
@@ -2984,6 +3258,7 @@
     /// <summary>Field number for the "latency_999" field.</summary>
     public const int Latency999FieldNumber = 11;
     private double latency999_;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public double Latency999 {
       get { return latency999_; }
       set {
@@ -2991,10 +3266,12 @@
       }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override bool Equals(object other) {
       return Equals(other as ScenarioResultSummary);
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public bool Equals(ScenarioResultSummary other) {
       if (ReferenceEquals(other, null)) {
         return false;
@@ -3016,6 +3293,7 @@
       return true;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override int GetHashCode() {
       int hash = 1;
       if (Qps != 0D) hash ^= Qps.GetHashCode();
@@ -3032,10 +3310,12 @@
       return hash;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override string ToString() {
       return pb::JsonFormatter.ToDiagnosticString(this);
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void WriteTo(pb::CodedOutputStream output) {
       if (Qps != 0D) {
         output.WriteRawTag(9);
@@ -3083,6 +3363,7 @@
       }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public int CalculateSize() {
       int size = 0;
       if (Qps != 0D) {
@@ -3121,6 +3402,7 @@
       return size;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void MergeFrom(ScenarioResultSummary other) {
       if (other == null) {
         return;
@@ -3160,6 +3442,7 @@
       }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void MergeFrom(pb::CodedInputStream input) {
       uint tag;
       while ((tag = input.ReadTag()) != 0) {
@@ -3220,25 +3503,29 @@
   /// <summary>
   ///  Results of a single benchmark scenario.
   /// </summary>
-  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
   public sealed partial class ScenarioResult : pb::IMessage<ScenarioResult> {
     private static readonly pb::MessageParser<ScenarioResult> _parser = new pb::MessageParser<ScenarioResult>(() => new ScenarioResult());
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pb::MessageParser<ScenarioResult> Parser { get { return _parser; } }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pbr::MessageDescriptor Descriptor {
       get { return global::Grpc.Testing.ControlReflection.Descriptor.MessageTypes[17]; }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     pbr::MessageDescriptor pb::IMessage.Descriptor {
       get { return Descriptor; }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public ScenarioResult() {
       OnConstruction();
     }
 
     partial void OnConstruction();
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public ScenarioResult(ScenarioResult other) : this() {
       Scenario = other.scenario_ != null ? other.Scenario.Clone() : null;
       Latencies = other.latencies_ != null ? other.Latencies.Clone() : null;
@@ -3246,8 +3533,11 @@
       serverStats_ = other.serverStats_.Clone();
       serverCores_ = other.serverCores_.Clone();
       Summary = other.summary_ != null ? other.Summary.Clone() : null;
+      clientSuccess_ = other.clientSuccess_.Clone();
+      serverSuccess_ = other.serverSuccess_.Clone();
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public ScenarioResult Clone() {
       return new ScenarioResult(this);
     }
@@ -3258,6 +3548,7 @@
     /// <summary>
     ///  Inputs used to run the scenario.
     /// </summary>
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public global::Grpc.Testing.Scenario Scenario {
       get { return scenario_; }
       set {
@@ -3271,6 +3562,7 @@
     /// <summary>
     ///  Histograms from all clients merged into one histogram.
     /// </summary>
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public global::Grpc.Testing.HistogramData Latencies {
       get { return latencies_; }
       set {
@@ -3286,6 +3578,7 @@
     /// <summary>
     ///  Client stats for each client
     /// </summary>
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public pbc::RepeatedField<global::Grpc.Testing.ClientStats> ClientStats {
       get { return clientStats_; }
     }
@@ -3298,6 +3591,7 @@
     /// <summary>
     ///  Server stats for each server
     /// </summary>
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public pbc::RepeatedField<global::Grpc.Testing.ServerStats> ServerStats {
       get { return serverStats_; }
     }
@@ -3310,6 +3604,7 @@
     /// <summary>
     ///  Number of cores available to each server
     /// </summary>
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public pbc::RepeatedField<int> ServerCores {
       get { return serverCores_; }
     }
@@ -3320,6 +3615,7 @@
     /// <summary>
     ///  An after-the-fact computed summary
     /// </summary>
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public global::Grpc.Testing.ScenarioResultSummary Summary {
       get { return summary_; }
       set {
@@ -3327,10 +3623,35 @@
       }
     }
 
+    /// <summary>Field number for the "client_success" field.</summary>
+    public const int ClientSuccessFieldNumber = 7;
+    private static readonly pb::FieldCodec<bool> _repeated_clientSuccess_codec
+        = pb::FieldCodec.ForBool(58);
+    private readonly pbc::RepeatedField<bool> clientSuccess_ = new pbc::RepeatedField<bool>();
+    /// <summary>
+    ///  Information on success or failure of each worker
+    /// </summary>
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public pbc::RepeatedField<bool> ClientSuccess {
+      get { return clientSuccess_; }
+    }
+
+    /// <summary>Field number for the "server_success" field.</summary>
+    public const int ServerSuccessFieldNumber = 8;
+    private static readonly pb::FieldCodec<bool> _repeated_serverSuccess_codec
+        = pb::FieldCodec.ForBool(66);
+    private readonly pbc::RepeatedField<bool> serverSuccess_ = new pbc::RepeatedField<bool>();
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public pbc::RepeatedField<bool> ServerSuccess {
+      get { return serverSuccess_; }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override bool Equals(object other) {
       return Equals(other as ScenarioResult);
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public bool Equals(ScenarioResult other) {
       if (ReferenceEquals(other, null)) {
         return false;
@@ -3344,9 +3665,12 @@
       if(!serverStats_.Equals(other.serverStats_)) return false;
       if(!serverCores_.Equals(other.serverCores_)) return false;
       if (!object.Equals(Summary, other.Summary)) return false;
+      if(!clientSuccess_.Equals(other.clientSuccess_)) return false;
+      if(!serverSuccess_.Equals(other.serverSuccess_)) return false;
       return true;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override int GetHashCode() {
       int hash = 1;
       if (scenario_ != null) hash ^= Scenario.GetHashCode();
@@ -3355,13 +3679,17 @@
       hash ^= serverStats_.GetHashCode();
       hash ^= serverCores_.GetHashCode();
       if (summary_ != null) hash ^= Summary.GetHashCode();
+      hash ^= clientSuccess_.GetHashCode();
+      hash ^= serverSuccess_.GetHashCode();
       return hash;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override string ToString() {
       return pb::JsonFormatter.ToDiagnosticString(this);
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void WriteTo(pb::CodedOutputStream output) {
       if (scenario_ != null) {
         output.WriteRawTag(10);
@@ -3378,8 +3706,11 @@
         output.WriteRawTag(50);
         output.WriteMessage(Summary);
       }
+      clientSuccess_.WriteTo(output, _repeated_clientSuccess_codec);
+      serverSuccess_.WriteTo(output, _repeated_serverSuccess_codec);
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public int CalculateSize() {
       int size = 0;
       if (scenario_ != null) {
@@ -3394,9 +3725,12 @@
       if (summary_ != null) {
         size += 1 + pb::CodedOutputStream.ComputeMessageSize(Summary);
       }
+      size += clientSuccess_.CalculateSize(_repeated_clientSuccess_codec);
+      size += serverSuccess_.CalculateSize(_repeated_serverSuccess_codec);
       return size;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void MergeFrom(ScenarioResult other) {
       if (other == null) {
         return;
@@ -3422,8 +3756,11 @@
         }
         Summary.MergeFrom(other.Summary);
       }
+      clientSuccess_.Add(other.clientSuccess_);
+      serverSuccess_.Add(other.serverSuccess_);
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void MergeFrom(pb::CodedInputStream input) {
       uint tag;
       while ((tag = input.ReadTag()) != 0) {
@@ -3465,6 +3802,16 @@
             input.ReadMessage(summary_);
             break;
           }
+          case 58:
+          case 56: {
+            clientSuccess_.AddEntriesFrom(input, _repeated_clientSuccess_codec);
+            break;
+          }
+          case 66:
+          case 64: {
+            serverSuccess_.AddEntriesFrom(input, _repeated_serverSuccess_codec);
+            break;
+          }
         }
       }
     }
diff --git a/src/csharp/Grpc.IntegrationTesting/Empty.cs b/src/csharp/Grpc.IntegrationTesting/Empty.cs
index cf1c23f..3017e66 100644
--- a/src/csharp/Grpc.IntegrationTesting/Empty.cs
+++ b/src/csharp/Grpc.IntegrationTesting/Empty.cs
@@ -10,7 +10,6 @@
 namespace Grpc.Testing {
 
   /// <summary>Holder for reflection information generated from src/proto/grpc/testing/empty.proto</summary>
-  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
   public static partial class EmptyReflection {
 
     #region Descriptor
@@ -44,36 +43,43 @@
   ///      rpc Bar (grpc.testing.Empty) returns (grpc.testing.Empty) { };
   ///    };
   /// </summary>
-  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
   public sealed partial class Empty : pb::IMessage<Empty> {
     private static readonly pb::MessageParser<Empty> _parser = new pb::MessageParser<Empty>(() => new Empty());
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pb::MessageParser<Empty> Parser { get { return _parser; } }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pbr::MessageDescriptor Descriptor {
       get { return global::Grpc.Testing.EmptyReflection.Descriptor.MessageTypes[0]; }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     pbr::MessageDescriptor pb::IMessage.Descriptor {
       get { return Descriptor; }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public Empty() {
       OnConstruction();
     }
 
     partial void OnConstruction();
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public Empty(Empty other) : this() {
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public Empty Clone() {
       return new Empty(this);
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override bool Equals(object other) {
       return Equals(other as Empty);
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public bool Equals(Empty other) {
       if (ReferenceEquals(other, null)) {
         return false;
@@ -84,29 +90,35 @@
       return true;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override int GetHashCode() {
       int hash = 1;
       return hash;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override string ToString() {
       return pb::JsonFormatter.ToDiagnosticString(this);
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void WriteTo(pb::CodedOutputStream output) {
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public int CalculateSize() {
       int size = 0;
       return size;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void MergeFrom(Empty other) {
       if (other == null) {
         return;
       }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void MergeFrom(pb::CodedInputStream input) {
       uint tag;
       while ((tag = input.ReadTag()) != 0) {
diff --git a/src/csharp/Grpc.IntegrationTesting/InteropClient.cs b/src/csharp/Grpc.IntegrationTesting/InteropClient.cs
index 79fd18b..cb92632 100644
--- a/src/csharp/Grpc.IntegrationTesting/InteropClient.cs
+++ b/src/csharp/Grpc.IntegrationTesting/InteropClient.cs
@@ -520,12 +520,12 @@
                 };
 
                 var call = client.FullDuplexCall(headers: CreateTestMetadata());
-                var responseHeaders = await call.ResponseHeadersAsync;
 
                 await call.RequestStream.WriteAsync(request);
                 await call.RequestStream.CompleteAsync();
                 await call.ResponseStream.ToListAsync();
 
+                var responseHeaders = await call.ResponseHeadersAsync;
                 var responseTrailers = call.GetTrailers();
 
                 Assert.AreEqual("test_initial_metadata_value", responseHeaders.First((entry) => entry.Key == "x-grpc-test-echo-initial").Value);
diff --git a/src/csharp/Grpc.IntegrationTesting/Messages.cs b/src/csharp/Grpc.IntegrationTesting/Messages.cs
index 1240db1..369fe73 100644
--- a/src/csharp/Grpc.IntegrationTesting/Messages.cs
+++ b/src/csharp/Grpc.IntegrationTesting/Messages.cs
@@ -10,7 +10,6 @@
 namespace Grpc.Testing {
 
   /// <summary>Holder for reflection information generated from src/proto/grpc/testing/messages.proto</summary>
-  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
   public static partial class MessagesReflection {
 
     #region Descriptor
@@ -94,29 +93,34 @@
   ///  https://github.com/grpc/grpc/issues/6980 has been fixed.
   ///  import "google/protobuf/wrappers.proto";
   /// </summary>
-  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
   public sealed partial class BoolValue : pb::IMessage<BoolValue> {
     private static readonly pb::MessageParser<BoolValue> _parser = new pb::MessageParser<BoolValue>(() => new BoolValue());
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pb::MessageParser<BoolValue> Parser { get { return _parser; } }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pbr::MessageDescriptor Descriptor {
       get { return global::Grpc.Testing.MessagesReflection.Descriptor.MessageTypes[0]; }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     pbr::MessageDescriptor pb::IMessage.Descriptor {
       get { return Descriptor; }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public BoolValue() {
       OnConstruction();
     }
 
     partial void OnConstruction();
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public BoolValue(BoolValue other) : this() {
       value_ = other.value_;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public BoolValue Clone() {
       return new BoolValue(this);
     }
@@ -127,6 +131,7 @@
     /// <summary>
     ///  The bool value.
     /// </summary>
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public bool Value {
       get { return value_; }
       set {
@@ -134,10 +139,12 @@
       }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override bool Equals(object other) {
       return Equals(other as BoolValue);
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public bool Equals(BoolValue other) {
       if (ReferenceEquals(other, null)) {
         return false;
@@ -149,16 +156,19 @@
       return true;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override int GetHashCode() {
       int hash = 1;
       if (Value != false) hash ^= Value.GetHashCode();
       return hash;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override string ToString() {
       return pb::JsonFormatter.ToDiagnosticString(this);
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void WriteTo(pb::CodedOutputStream output) {
       if (Value != false) {
         output.WriteRawTag(8);
@@ -166,6 +176,7 @@
       }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public int CalculateSize() {
       int size = 0;
       if (Value != false) {
@@ -174,6 +185,7 @@
       return size;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void MergeFrom(BoolValue other) {
       if (other == null) {
         return;
@@ -183,6 +195,7 @@
       }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void MergeFrom(pb::CodedInputStream input) {
       uint tag;
       while ((tag = input.ReadTag()) != 0) {
@@ -203,30 +216,35 @@
   /// <summary>
   ///  A block of data, to simply increase gRPC message size.
   /// </summary>
-  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
   public sealed partial class Payload : pb::IMessage<Payload> {
     private static readonly pb::MessageParser<Payload> _parser = new pb::MessageParser<Payload>(() => new Payload());
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pb::MessageParser<Payload> Parser { get { return _parser; } }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pbr::MessageDescriptor Descriptor {
       get { return global::Grpc.Testing.MessagesReflection.Descriptor.MessageTypes[1]; }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     pbr::MessageDescriptor pb::IMessage.Descriptor {
       get { return Descriptor; }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public Payload() {
       OnConstruction();
     }
 
     partial void OnConstruction();
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public Payload(Payload other) : this() {
       type_ = other.type_;
       body_ = other.body_;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public Payload Clone() {
       return new Payload(this);
     }
@@ -238,6 +256,7 @@
     ///  DEPRECATED, don't use. To be removed shortly.
     ///  The type of data in body.
     /// </summary>
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public global::Grpc.Testing.PayloadType Type {
       get { return type_; }
       set {
@@ -251,6 +270,7 @@
     /// <summary>
     ///  Primary contents of payload.
     /// </summary>
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public pb::ByteString Body {
       get { return body_; }
       set {
@@ -258,10 +278,12 @@
       }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override bool Equals(object other) {
       return Equals(other as Payload);
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public bool Equals(Payload other) {
       if (ReferenceEquals(other, null)) {
         return false;
@@ -274,6 +296,7 @@
       return true;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override int GetHashCode() {
       int hash = 1;
       if (Type != 0) hash ^= Type.GetHashCode();
@@ -281,10 +304,12 @@
       return hash;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override string ToString() {
       return pb::JsonFormatter.ToDiagnosticString(this);
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void WriteTo(pb::CodedOutputStream output) {
       if (Type != 0) {
         output.WriteRawTag(8);
@@ -296,6 +321,7 @@
       }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public int CalculateSize() {
       int size = 0;
       if (Type != 0) {
@@ -307,6 +333,7 @@
       return size;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void MergeFrom(Payload other) {
       if (other == null) {
         return;
@@ -319,6 +346,7 @@
       }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void MergeFrom(pb::CodedInputStream input) {
       uint tag;
       while ((tag = input.ReadTag()) != 0) {
@@ -344,30 +372,35 @@
   ///  A protobuf representation for grpc status. This is used by test
   ///  clients to specify a status that the server should attempt to return.
   /// </summary>
-  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
   public sealed partial class EchoStatus : pb::IMessage<EchoStatus> {
     private static readonly pb::MessageParser<EchoStatus> _parser = new pb::MessageParser<EchoStatus>(() => new EchoStatus());
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pb::MessageParser<EchoStatus> Parser { get { return _parser; } }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pbr::MessageDescriptor Descriptor {
       get { return global::Grpc.Testing.MessagesReflection.Descriptor.MessageTypes[2]; }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     pbr::MessageDescriptor pb::IMessage.Descriptor {
       get { return Descriptor; }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public EchoStatus() {
       OnConstruction();
     }
 
     partial void OnConstruction();
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public EchoStatus(EchoStatus other) : this() {
       code_ = other.code_;
       message_ = other.message_;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public EchoStatus Clone() {
       return new EchoStatus(this);
     }
@@ -375,6 +408,7 @@
     /// <summary>Field number for the "code" field.</summary>
     public const int CodeFieldNumber = 1;
     private int code_;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public int Code {
       get { return code_; }
       set {
@@ -385,6 +419,7 @@
     /// <summary>Field number for the "message" field.</summary>
     public const int MessageFieldNumber = 2;
     private string message_ = "";
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public string Message {
       get { return message_; }
       set {
@@ -392,10 +427,12 @@
       }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override bool Equals(object other) {
       return Equals(other as EchoStatus);
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public bool Equals(EchoStatus other) {
       if (ReferenceEquals(other, null)) {
         return false;
@@ -408,6 +445,7 @@
       return true;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override int GetHashCode() {
       int hash = 1;
       if (Code != 0) hash ^= Code.GetHashCode();
@@ -415,10 +453,12 @@
       return hash;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override string ToString() {
       return pb::JsonFormatter.ToDiagnosticString(this);
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void WriteTo(pb::CodedOutputStream output) {
       if (Code != 0) {
         output.WriteRawTag(8);
@@ -430,6 +470,7 @@
       }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public int CalculateSize() {
       int size = 0;
       if (Code != 0) {
@@ -441,6 +482,7 @@
       return size;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void MergeFrom(EchoStatus other) {
       if (other == null) {
         return;
@@ -453,6 +495,7 @@
       }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void MergeFrom(pb::CodedInputStream input) {
       uint tag;
       while ((tag = input.ReadTag()) != 0) {
@@ -477,25 +520,29 @@
   /// <summary>
   ///  Unary request.
   /// </summary>
-  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
   public sealed partial class SimpleRequest : pb::IMessage<SimpleRequest> {
     private static readonly pb::MessageParser<SimpleRequest> _parser = new pb::MessageParser<SimpleRequest>(() => new SimpleRequest());
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pb::MessageParser<SimpleRequest> Parser { get { return _parser; } }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pbr::MessageDescriptor Descriptor {
       get { return global::Grpc.Testing.MessagesReflection.Descriptor.MessageTypes[3]; }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     pbr::MessageDescriptor pb::IMessage.Descriptor {
       get { return Descriptor; }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public SimpleRequest() {
       OnConstruction();
     }
 
     partial void OnConstruction();
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public SimpleRequest(SimpleRequest other) : this() {
       responseType_ = other.responseType_;
       responseSize_ = other.responseSize_;
@@ -507,6 +554,7 @@
       ExpectCompressed = other.expectCompressed_ != null ? other.ExpectCompressed.Clone() : null;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public SimpleRequest Clone() {
       return new SimpleRequest(this);
     }
@@ -519,6 +567,7 @@
     ///  Desired payload type in the response from the server.
     ///  If response_type is RANDOM, server randomly chooses one from other formats.
     /// </summary>
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public global::Grpc.Testing.PayloadType ResponseType {
       get { return responseType_; }
       set {
@@ -532,6 +581,7 @@
     /// <summary>
     ///  Desired payload size in the response from the server.
     /// </summary>
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public int ResponseSize {
       get { return responseSize_; }
       set {
@@ -545,6 +595,7 @@
     /// <summary>
     ///  Optional input payload sent along with the request.
     /// </summary>
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public global::Grpc.Testing.Payload Payload {
       get { return payload_; }
       set {
@@ -558,6 +609,7 @@
     /// <summary>
     ///  Whether SimpleResponse should include username.
     /// </summary>
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public bool FillUsername {
       get { return fillUsername_; }
       set {
@@ -571,6 +623,7 @@
     /// <summary>
     ///  Whether SimpleResponse should include OAuth scope.
     /// </summary>
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public bool FillOauthScope {
       get { return fillOauthScope_; }
       set {
@@ -587,6 +640,7 @@
     ///  implement the full compression tests by introspecting the call to verify
     ///  the response's compression status.
     /// </summary>
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public global::Grpc.Testing.BoolValue ResponseCompressed {
       get { return responseCompressed_; }
       set {
@@ -600,6 +654,7 @@
     /// <summary>
     ///  Whether server should return a given status
     /// </summary>
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public global::Grpc.Testing.EchoStatus ResponseStatus {
       get { return responseStatus_; }
       set {
@@ -613,6 +668,7 @@
     /// <summary>
     ///  Whether the server should expect this request to be compressed.
     /// </summary>
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public global::Grpc.Testing.BoolValue ExpectCompressed {
       get { return expectCompressed_; }
       set {
@@ -620,10 +676,12 @@
       }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override bool Equals(object other) {
       return Equals(other as SimpleRequest);
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public bool Equals(SimpleRequest other) {
       if (ReferenceEquals(other, null)) {
         return false;
@@ -642,6 +700,7 @@
       return true;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override int GetHashCode() {
       int hash = 1;
       if (ResponseType != 0) hash ^= ResponseType.GetHashCode();
@@ -655,10 +714,12 @@
       return hash;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override string ToString() {
       return pb::JsonFormatter.ToDiagnosticString(this);
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void WriteTo(pb::CodedOutputStream output) {
       if (ResponseType != 0) {
         output.WriteRawTag(8);
@@ -694,6 +755,7 @@
       }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public int CalculateSize() {
       int size = 0;
       if (ResponseType != 0) {
@@ -723,6 +785,7 @@
       return size;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void MergeFrom(SimpleRequest other) {
       if (other == null) {
         return;
@@ -765,6 +828,7 @@
       }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void MergeFrom(pb::CodedInputStream input) {
       uint tag;
       while ((tag = input.ReadTag()) != 0) {
@@ -825,31 +889,36 @@
   /// <summary>
   ///  Unary response, as configured by the request.
   /// </summary>
-  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
   public sealed partial class SimpleResponse : pb::IMessage<SimpleResponse> {
     private static readonly pb::MessageParser<SimpleResponse> _parser = new pb::MessageParser<SimpleResponse>(() => new SimpleResponse());
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pb::MessageParser<SimpleResponse> Parser { get { return _parser; } }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pbr::MessageDescriptor Descriptor {
       get { return global::Grpc.Testing.MessagesReflection.Descriptor.MessageTypes[4]; }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     pbr::MessageDescriptor pb::IMessage.Descriptor {
       get { return Descriptor; }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public SimpleResponse() {
       OnConstruction();
     }
 
     partial void OnConstruction();
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public SimpleResponse(SimpleResponse other) : this() {
       Payload = other.payload_ != null ? other.Payload.Clone() : null;
       username_ = other.username_;
       oauthScope_ = other.oauthScope_;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public SimpleResponse Clone() {
       return new SimpleResponse(this);
     }
@@ -860,6 +929,7 @@
     /// <summary>
     ///  Payload to increase message size.
     /// </summary>
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public global::Grpc.Testing.Payload Payload {
       get { return payload_; }
       set {
@@ -874,6 +944,7 @@
     ///  The user the request came from, for verifying authentication was
     ///  successful when the client expected it.
     /// </summary>
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public string Username {
       get { return username_; }
       set {
@@ -887,6 +958,7 @@
     /// <summary>
     ///  OAuth scope.
     /// </summary>
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public string OauthScope {
       get { return oauthScope_; }
       set {
@@ -894,10 +966,12 @@
       }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override bool Equals(object other) {
       return Equals(other as SimpleResponse);
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public bool Equals(SimpleResponse other) {
       if (ReferenceEquals(other, null)) {
         return false;
@@ -911,6 +985,7 @@
       return true;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override int GetHashCode() {
       int hash = 1;
       if (payload_ != null) hash ^= Payload.GetHashCode();
@@ -919,10 +994,12 @@
       return hash;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override string ToString() {
       return pb::JsonFormatter.ToDiagnosticString(this);
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void WriteTo(pb::CodedOutputStream output) {
       if (payload_ != null) {
         output.WriteRawTag(10);
@@ -938,6 +1015,7 @@
       }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public int CalculateSize() {
       int size = 0;
       if (payload_ != null) {
@@ -952,6 +1030,7 @@
       return size;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void MergeFrom(SimpleResponse other) {
       if (other == null) {
         return;
@@ -970,6 +1049,7 @@
       }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void MergeFrom(pb::CodedInputStream input) {
       uint tag;
       while ((tag = input.ReadTag()) != 0) {
@@ -1001,30 +1081,35 @@
   /// <summary>
   ///  Client-streaming request.
   /// </summary>
-  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
   public sealed partial class StreamingInputCallRequest : pb::IMessage<StreamingInputCallRequest> {
     private static readonly pb::MessageParser<StreamingInputCallRequest> _parser = new pb::MessageParser<StreamingInputCallRequest>(() => new StreamingInputCallRequest());
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pb::MessageParser<StreamingInputCallRequest> Parser { get { return _parser; } }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pbr::MessageDescriptor Descriptor {
       get { return global::Grpc.Testing.MessagesReflection.Descriptor.MessageTypes[5]; }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     pbr::MessageDescriptor pb::IMessage.Descriptor {
       get { return Descriptor; }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public StreamingInputCallRequest() {
       OnConstruction();
     }
 
     partial void OnConstruction();
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public StreamingInputCallRequest(StreamingInputCallRequest other) : this() {
       Payload = other.payload_ != null ? other.Payload.Clone() : null;
       ExpectCompressed = other.expectCompressed_ != null ? other.ExpectCompressed.Clone() : null;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public StreamingInputCallRequest Clone() {
       return new StreamingInputCallRequest(this);
     }
@@ -1035,6 +1120,7 @@
     /// <summary>
     ///  Optional input payload sent along with the request.
     /// </summary>
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public global::Grpc.Testing.Payload Payload {
       get { return payload_; }
       set {
@@ -1051,6 +1137,7 @@
     ///  implement the full compression tests by introspecting the call to verify
     ///  the request's compression status.
     /// </summary>
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public global::Grpc.Testing.BoolValue ExpectCompressed {
       get { return expectCompressed_; }
       set {
@@ -1058,10 +1145,12 @@
       }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override bool Equals(object other) {
       return Equals(other as StreamingInputCallRequest);
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public bool Equals(StreamingInputCallRequest other) {
       if (ReferenceEquals(other, null)) {
         return false;
@@ -1074,6 +1163,7 @@
       return true;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override int GetHashCode() {
       int hash = 1;
       if (payload_ != null) hash ^= Payload.GetHashCode();
@@ -1081,10 +1171,12 @@
       return hash;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override string ToString() {
       return pb::JsonFormatter.ToDiagnosticString(this);
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void WriteTo(pb::CodedOutputStream output) {
       if (payload_ != null) {
         output.WriteRawTag(10);
@@ -1096,6 +1188,7 @@
       }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public int CalculateSize() {
       int size = 0;
       if (payload_ != null) {
@@ -1107,6 +1200,7 @@
       return size;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void MergeFrom(StreamingInputCallRequest other) {
       if (other == null) {
         return;
@@ -1125,6 +1219,7 @@
       }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void MergeFrom(pb::CodedInputStream input) {
       uint tag;
       while ((tag = input.ReadTag()) != 0) {
@@ -1155,29 +1250,34 @@
   /// <summary>
   ///  Client-streaming response.
   /// </summary>
-  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
   public sealed partial class StreamingInputCallResponse : pb::IMessage<StreamingInputCallResponse> {
     private static readonly pb::MessageParser<StreamingInputCallResponse> _parser = new pb::MessageParser<StreamingInputCallResponse>(() => new StreamingInputCallResponse());
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pb::MessageParser<StreamingInputCallResponse> Parser { get { return _parser; } }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pbr::MessageDescriptor Descriptor {
       get { return global::Grpc.Testing.MessagesReflection.Descriptor.MessageTypes[6]; }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     pbr::MessageDescriptor pb::IMessage.Descriptor {
       get { return Descriptor; }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public StreamingInputCallResponse() {
       OnConstruction();
     }
 
     partial void OnConstruction();
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public StreamingInputCallResponse(StreamingInputCallResponse other) : this() {
       aggregatedPayloadSize_ = other.aggregatedPayloadSize_;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public StreamingInputCallResponse Clone() {
       return new StreamingInputCallResponse(this);
     }
@@ -1188,6 +1288,7 @@
     /// <summary>
     ///  Aggregated size of payloads received from the client.
     /// </summary>
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public int AggregatedPayloadSize {
       get { return aggregatedPayloadSize_; }
       set {
@@ -1195,10 +1296,12 @@
       }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override bool Equals(object other) {
       return Equals(other as StreamingInputCallResponse);
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public bool Equals(StreamingInputCallResponse other) {
       if (ReferenceEquals(other, null)) {
         return false;
@@ -1210,16 +1313,19 @@
       return true;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override int GetHashCode() {
       int hash = 1;
       if (AggregatedPayloadSize != 0) hash ^= AggregatedPayloadSize.GetHashCode();
       return hash;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override string ToString() {
       return pb::JsonFormatter.ToDiagnosticString(this);
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void WriteTo(pb::CodedOutputStream output) {
       if (AggregatedPayloadSize != 0) {
         output.WriteRawTag(8);
@@ -1227,6 +1333,7 @@
       }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public int CalculateSize() {
       int size = 0;
       if (AggregatedPayloadSize != 0) {
@@ -1235,6 +1342,7 @@
       return size;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void MergeFrom(StreamingInputCallResponse other) {
       if (other == null) {
         return;
@@ -1244,6 +1352,7 @@
       }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void MergeFrom(pb::CodedInputStream input) {
       uint tag;
       while ((tag = input.ReadTag()) != 0) {
@@ -1264,31 +1373,36 @@
   /// <summary>
   ///  Configuration for a particular response.
   /// </summary>
-  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
   public sealed partial class ResponseParameters : pb::IMessage<ResponseParameters> {
     private static readonly pb::MessageParser<ResponseParameters> _parser = new pb::MessageParser<ResponseParameters>(() => new ResponseParameters());
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pb::MessageParser<ResponseParameters> Parser { get { return _parser; } }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pbr::MessageDescriptor Descriptor {
       get { return global::Grpc.Testing.MessagesReflection.Descriptor.MessageTypes[7]; }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     pbr::MessageDescriptor pb::IMessage.Descriptor {
       get { return Descriptor; }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public ResponseParameters() {
       OnConstruction();
     }
 
     partial void OnConstruction();
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public ResponseParameters(ResponseParameters other) : this() {
       size_ = other.size_;
       intervalUs_ = other.intervalUs_;
       Compressed = other.compressed_ != null ? other.Compressed.Clone() : null;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public ResponseParameters Clone() {
       return new ResponseParameters(this);
     }
@@ -1299,6 +1413,7 @@
     /// <summary>
     ///  Desired payload sizes in responses from the server.
     /// </summary>
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public int Size {
       get { return size_; }
       set {
@@ -1313,6 +1428,7 @@
     ///  Desired interval between consecutive responses in the response stream in
     ///  microseconds.
     /// </summary>
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public int IntervalUs {
       get { return intervalUs_; }
       set {
@@ -1329,6 +1445,7 @@
     ///  implement the full compression tests by introspecting the call to verify
     ///  the response's compression status.
     /// </summary>
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public global::Grpc.Testing.BoolValue Compressed {
       get { return compressed_; }
       set {
@@ -1336,10 +1453,12 @@
       }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override bool Equals(object other) {
       return Equals(other as ResponseParameters);
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public bool Equals(ResponseParameters other) {
       if (ReferenceEquals(other, null)) {
         return false;
@@ -1353,6 +1472,7 @@
       return true;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override int GetHashCode() {
       int hash = 1;
       if (Size != 0) hash ^= Size.GetHashCode();
@@ -1361,10 +1481,12 @@
       return hash;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override string ToString() {
       return pb::JsonFormatter.ToDiagnosticString(this);
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void WriteTo(pb::CodedOutputStream output) {
       if (Size != 0) {
         output.WriteRawTag(8);
@@ -1380,6 +1502,7 @@
       }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public int CalculateSize() {
       int size = 0;
       if (Size != 0) {
@@ -1394,6 +1517,7 @@
       return size;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void MergeFrom(ResponseParameters other) {
       if (other == null) {
         return;
@@ -1412,6 +1536,7 @@
       }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void MergeFrom(pb::CodedInputStream input) {
       uint tag;
       while ((tag = input.ReadTag()) != 0) {
@@ -1443,25 +1568,29 @@
   /// <summary>
   ///  Server-streaming request.
   /// </summary>
-  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
   public sealed partial class StreamingOutputCallRequest : pb::IMessage<StreamingOutputCallRequest> {
     private static readonly pb::MessageParser<StreamingOutputCallRequest> _parser = new pb::MessageParser<StreamingOutputCallRequest>(() => new StreamingOutputCallRequest());
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pb::MessageParser<StreamingOutputCallRequest> Parser { get { return _parser; } }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pbr::MessageDescriptor Descriptor {
       get { return global::Grpc.Testing.MessagesReflection.Descriptor.MessageTypes[8]; }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     pbr::MessageDescriptor pb::IMessage.Descriptor {
       get { return Descriptor; }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public StreamingOutputCallRequest() {
       OnConstruction();
     }
 
     partial void OnConstruction();
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public StreamingOutputCallRequest(StreamingOutputCallRequest other) : this() {
       responseType_ = other.responseType_;
       responseParameters_ = other.responseParameters_.Clone();
@@ -1469,6 +1598,7 @@
       ResponseStatus = other.responseStatus_ != null ? other.ResponseStatus.Clone() : null;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public StreamingOutputCallRequest Clone() {
       return new StreamingOutputCallRequest(this);
     }
@@ -1483,6 +1613,7 @@
     ///  might be of different types. This is to simulate a mixed type of payload
     ///  stream.
     /// </summary>
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public global::Grpc.Testing.PayloadType ResponseType {
       get { return responseType_; }
       set {
@@ -1498,6 +1629,7 @@
     /// <summary>
     ///  Configuration for each expected response message.
     /// </summary>
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public pbc::RepeatedField<global::Grpc.Testing.ResponseParameters> ResponseParameters {
       get { return responseParameters_; }
     }
@@ -1508,6 +1640,7 @@
     /// <summary>
     ///  Optional input payload sent along with the request.
     /// </summary>
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public global::Grpc.Testing.Payload Payload {
       get { return payload_; }
       set {
@@ -1521,6 +1654,7 @@
     /// <summary>
     ///  Whether server should return a given status
     /// </summary>
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public global::Grpc.Testing.EchoStatus ResponseStatus {
       get { return responseStatus_; }
       set {
@@ -1528,10 +1662,12 @@
       }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override bool Equals(object other) {
       return Equals(other as StreamingOutputCallRequest);
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public bool Equals(StreamingOutputCallRequest other) {
       if (ReferenceEquals(other, null)) {
         return false;
@@ -1546,6 +1682,7 @@
       return true;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override int GetHashCode() {
       int hash = 1;
       if (ResponseType != 0) hash ^= ResponseType.GetHashCode();
@@ -1555,10 +1692,12 @@
       return hash;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override string ToString() {
       return pb::JsonFormatter.ToDiagnosticString(this);
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void WriteTo(pb::CodedOutputStream output) {
       if (ResponseType != 0) {
         output.WriteRawTag(8);
@@ -1575,6 +1714,7 @@
       }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public int CalculateSize() {
       int size = 0;
       if (ResponseType != 0) {
@@ -1590,6 +1730,7 @@
       return size;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void MergeFrom(StreamingOutputCallRequest other) {
       if (other == null) {
         return;
@@ -1612,6 +1753,7 @@
       }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void MergeFrom(pb::CodedInputStream input) {
       uint tag;
       while ((tag = input.ReadTag()) != 0) {
@@ -1650,29 +1792,34 @@
   /// <summary>
   ///  Server-streaming response, as configured by the request and parameters.
   /// </summary>
-  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
   public sealed partial class StreamingOutputCallResponse : pb::IMessage<StreamingOutputCallResponse> {
     private static readonly pb::MessageParser<StreamingOutputCallResponse> _parser = new pb::MessageParser<StreamingOutputCallResponse>(() => new StreamingOutputCallResponse());
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pb::MessageParser<StreamingOutputCallResponse> Parser { get { return _parser; } }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pbr::MessageDescriptor Descriptor {
       get { return global::Grpc.Testing.MessagesReflection.Descriptor.MessageTypes[9]; }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     pbr::MessageDescriptor pb::IMessage.Descriptor {
       get { return Descriptor; }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public StreamingOutputCallResponse() {
       OnConstruction();
     }
 
     partial void OnConstruction();
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public StreamingOutputCallResponse(StreamingOutputCallResponse other) : this() {
       Payload = other.payload_ != null ? other.Payload.Clone() : null;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public StreamingOutputCallResponse Clone() {
       return new StreamingOutputCallResponse(this);
     }
@@ -1683,6 +1830,7 @@
     /// <summary>
     ///  Payload to increase response size.
     /// </summary>
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public global::Grpc.Testing.Payload Payload {
       get { return payload_; }
       set {
@@ -1690,10 +1838,12 @@
       }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override bool Equals(object other) {
       return Equals(other as StreamingOutputCallResponse);
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public bool Equals(StreamingOutputCallResponse other) {
       if (ReferenceEquals(other, null)) {
         return false;
@@ -1705,16 +1855,19 @@
       return true;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override int GetHashCode() {
       int hash = 1;
       if (payload_ != null) hash ^= Payload.GetHashCode();
       return hash;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override string ToString() {
       return pb::JsonFormatter.ToDiagnosticString(this);
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void WriteTo(pb::CodedOutputStream output) {
       if (payload_ != null) {
         output.WriteRawTag(10);
@@ -1722,6 +1875,7 @@
       }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public int CalculateSize() {
       int size = 0;
       if (payload_ != null) {
@@ -1730,6 +1884,7 @@
       return size;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void MergeFrom(StreamingOutputCallResponse other) {
       if (other == null) {
         return;
@@ -1742,6 +1897,7 @@
       }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void MergeFrom(pb::CodedInputStream input) {
       uint tag;
       while ((tag = input.ReadTag()) != 0) {
@@ -1766,29 +1922,34 @@
   ///  For reconnect interop test only.
   ///  Client tells server what reconnection parameters it used.
   /// </summary>
-  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
   public sealed partial class ReconnectParams : pb::IMessage<ReconnectParams> {
     private static readonly pb::MessageParser<ReconnectParams> _parser = new pb::MessageParser<ReconnectParams>(() => new ReconnectParams());
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pb::MessageParser<ReconnectParams> Parser { get { return _parser; } }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pbr::MessageDescriptor Descriptor {
       get { return global::Grpc.Testing.MessagesReflection.Descriptor.MessageTypes[10]; }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     pbr::MessageDescriptor pb::IMessage.Descriptor {
       get { return Descriptor; }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public ReconnectParams() {
       OnConstruction();
     }
 
     partial void OnConstruction();
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public ReconnectParams(ReconnectParams other) : this() {
       maxReconnectBackoffMs_ = other.maxReconnectBackoffMs_;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public ReconnectParams Clone() {
       return new ReconnectParams(this);
     }
@@ -1796,6 +1957,7 @@
     /// <summary>Field number for the "max_reconnect_backoff_ms" field.</summary>
     public const int MaxReconnectBackoffMsFieldNumber = 1;
     private int maxReconnectBackoffMs_;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public int MaxReconnectBackoffMs {
       get { return maxReconnectBackoffMs_; }
       set {
@@ -1803,10 +1965,12 @@
       }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override bool Equals(object other) {
       return Equals(other as ReconnectParams);
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public bool Equals(ReconnectParams other) {
       if (ReferenceEquals(other, null)) {
         return false;
@@ -1818,16 +1982,19 @@
       return true;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override int GetHashCode() {
       int hash = 1;
       if (MaxReconnectBackoffMs != 0) hash ^= MaxReconnectBackoffMs.GetHashCode();
       return hash;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override string ToString() {
       return pb::JsonFormatter.ToDiagnosticString(this);
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void WriteTo(pb::CodedOutputStream output) {
       if (MaxReconnectBackoffMs != 0) {
         output.WriteRawTag(8);
@@ -1835,6 +2002,7 @@
       }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public int CalculateSize() {
       int size = 0;
       if (MaxReconnectBackoffMs != 0) {
@@ -1843,6 +2011,7 @@
       return size;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void MergeFrom(ReconnectParams other) {
       if (other == null) {
         return;
@@ -1852,6 +2021,7 @@
       }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void MergeFrom(pb::CodedInputStream input) {
       uint tag;
       while ((tag = input.ReadTag()) != 0) {
@@ -1874,30 +2044,35 @@
   ///  Server tells client whether its reconnects are following the spec and the
   ///  reconnect backoffs it saw.
   /// </summary>
-  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
   public sealed partial class ReconnectInfo : pb::IMessage<ReconnectInfo> {
     private static readonly pb::MessageParser<ReconnectInfo> _parser = new pb::MessageParser<ReconnectInfo>(() => new ReconnectInfo());
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pb::MessageParser<ReconnectInfo> Parser { get { return _parser; } }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pbr::MessageDescriptor Descriptor {
       get { return global::Grpc.Testing.MessagesReflection.Descriptor.MessageTypes[11]; }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     pbr::MessageDescriptor pb::IMessage.Descriptor {
       get { return Descriptor; }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public ReconnectInfo() {
       OnConstruction();
     }
 
     partial void OnConstruction();
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public ReconnectInfo(ReconnectInfo other) : this() {
       passed_ = other.passed_;
       backoffMs_ = other.backoffMs_.Clone();
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public ReconnectInfo Clone() {
       return new ReconnectInfo(this);
     }
@@ -1905,6 +2080,7 @@
     /// <summary>Field number for the "passed" field.</summary>
     public const int PassedFieldNumber = 1;
     private bool passed_;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public bool Passed {
       get { return passed_; }
       set {
@@ -1917,14 +2093,17 @@
     private static readonly pb::FieldCodec<int> _repeated_backoffMs_codec
         = pb::FieldCodec.ForInt32(18);
     private readonly pbc::RepeatedField<int> backoffMs_ = new pbc::RepeatedField<int>();
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public pbc::RepeatedField<int> BackoffMs {
       get { return backoffMs_; }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override bool Equals(object other) {
       return Equals(other as ReconnectInfo);
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public bool Equals(ReconnectInfo other) {
       if (ReferenceEquals(other, null)) {
         return false;
@@ -1937,6 +2116,7 @@
       return true;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override int GetHashCode() {
       int hash = 1;
       if (Passed != false) hash ^= Passed.GetHashCode();
@@ -1944,10 +2124,12 @@
       return hash;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override string ToString() {
       return pb::JsonFormatter.ToDiagnosticString(this);
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void WriteTo(pb::CodedOutputStream output) {
       if (Passed != false) {
         output.WriteRawTag(8);
@@ -1956,6 +2138,7 @@
       backoffMs_.WriteTo(output, _repeated_backoffMs_codec);
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public int CalculateSize() {
       int size = 0;
       if (Passed != false) {
@@ -1965,6 +2148,7 @@
       return size;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void MergeFrom(ReconnectInfo other) {
       if (other == null) {
         return;
@@ -1975,6 +2159,7 @@
       backoffMs_.Add(other.backoffMs_);
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void MergeFrom(pb::CodedInputStream input) {
       uint tag;
       while ((tag = input.ReadTag()) != 0) {
diff --git a/src/csharp/Grpc.IntegrationTesting/Metrics.cs b/src/csharp/Grpc.IntegrationTesting/Metrics.cs
index 8f31fbc..4de1847 100644
--- a/src/csharp/Grpc.IntegrationTesting/Metrics.cs
+++ b/src/csharp/Grpc.IntegrationTesting/Metrics.cs
@@ -10,7 +10,6 @@
 namespace Grpc.Testing {
 
   /// <summary>Holder for reflection information generated from src/proto/grpc/testing/metrics.proto</summary>
-  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
   public static partial class MetricsReflection {
 
     #region Descriptor
@@ -47,25 +46,29 @@
   /// <summary>
   ///  Reponse message containing the gauge name and value
   /// </summary>
-  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
   public sealed partial class GaugeResponse : pb::IMessage<GaugeResponse> {
     private static readonly pb::MessageParser<GaugeResponse> _parser = new pb::MessageParser<GaugeResponse>(() => new GaugeResponse());
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pb::MessageParser<GaugeResponse> Parser { get { return _parser; } }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pbr::MessageDescriptor Descriptor {
       get { return global::Grpc.Testing.MetricsReflection.Descriptor.MessageTypes[0]; }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     pbr::MessageDescriptor pb::IMessage.Descriptor {
       get { return Descriptor; }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public GaugeResponse() {
       OnConstruction();
     }
 
     partial void OnConstruction();
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public GaugeResponse(GaugeResponse other) : this() {
       name_ = other.name_;
       switch (other.ValueCase) {
@@ -82,6 +85,7 @@
 
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public GaugeResponse Clone() {
       return new GaugeResponse(this);
     }
@@ -89,6 +93,7 @@
     /// <summary>Field number for the "name" field.</summary>
     public const int NameFieldNumber = 1;
     private string name_ = "";
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public string Name {
       get { return name_; }
       set {
@@ -98,6 +103,7 @@
 
     /// <summary>Field number for the "long_value" field.</summary>
     public const int LongValueFieldNumber = 2;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public long LongValue {
       get { return valueCase_ == ValueOneofCase.LongValue ? (long) value_ : 0L; }
       set {
@@ -108,6 +114,7 @@
 
     /// <summary>Field number for the "double_value" field.</summary>
     public const int DoubleValueFieldNumber = 3;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public double DoubleValue {
       get { return valueCase_ == ValueOneofCase.DoubleValue ? (double) value_ : 0D; }
       set {
@@ -118,6 +125,7 @@
 
     /// <summary>Field number for the "string_value" field.</summary>
     public const int StringValueFieldNumber = 4;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public string StringValue {
       get { return valueCase_ == ValueOneofCase.StringValue ? (string) value_ : ""; }
       set {
@@ -135,19 +143,23 @@
       StringValue = 4,
     }
     private ValueOneofCase valueCase_ = ValueOneofCase.None;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public ValueOneofCase ValueCase {
       get { return valueCase_; }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void ClearValue() {
       valueCase_ = ValueOneofCase.None;
       value_ = null;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override bool Equals(object other) {
       return Equals(other as GaugeResponse);
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public bool Equals(GaugeResponse other) {
       if (ReferenceEquals(other, null)) {
         return false;
@@ -163,6 +175,7 @@
       return true;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override int GetHashCode() {
       int hash = 1;
       if (Name.Length != 0) hash ^= Name.GetHashCode();
@@ -173,10 +186,12 @@
       return hash;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override string ToString() {
       return pb::JsonFormatter.ToDiagnosticString(this);
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void WriteTo(pb::CodedOutputStream output) {
       if (Name.Length != 0) {
         output.WriteRawTag(10);
@@ -196,6 +211,7 @@
       }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public int CalculateSize() {
       int size = 0;
       if (Name.Length != 0) {
@@ -213,6 +229,7 @@
       return size;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void MergeFrom(GaugeResponse other) {
       if (other == null) {
         return;
@@ -234,6 +251,7 @@
 
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void MergeFrom(pb::CodedInputStream input) {
       uint tag;
       while ((tag = input.ReadTag()) != 0) {
@@ -266,29 +284,34 @@
   /// <summary>
   ///  Request message containing the gauge name
   /// </summary>
-  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
   public sealed partial class GaugeRequest : pb::IMessage<GaugeRequest> {
     private static readonly pb::MessageParser<GaugeRequest> _parser = new pb::MessageParser<GaugeRequest>(() => new GaugeRequest());
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pb::MessageParser<GaugeRequest> Parser { get { return _parser; } }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pbr::MessageDescriptor Descriptor {
       get { return global::Grpc.Testing.MetricsReflection.Descriptor.MessageTypes[1]; }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     pbr::MessageDescriptor pb::IMessage.Descriptor {
       get { return Descriptor; }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public GaugeRequest() {
       OnConstruction();
     }
 
     partial void OnConstruction();
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public GaugeRequest(GaugeRequest other) : this() {
       name_ = other.name_;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public GaugeRequest Clone() {
       return new GaugeRequest(this);
     }
@@ -296,6 +319,7 @@
     /// <summary>Field number for the "name" field.</summary>
     public const int NameFieldNumber = 1;
     private string name_ = "";
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public string Name {
       get { return name_; }
       set {
@@ -303,10 +327,12 @@
       }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override bool Equals(object other) {
       return Equals(other as GaugeRequest);
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public bool Equals(GaugeRequest other) {
       if (ReferenceEquals(other, null)) {
         return false;
@@ -318,16 +344,19 @@
       return true;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override int GetHashCode() {
       int hash = 1;
       if (Name.Length != 0) hash ^= Name.GetHashCode();
       return hash;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override string ToString() {
       return pb::JsonFormatter.ToDiagnosticString(this);
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void WriteTo(pb::CodedOutputStream output) {
       if (Name.Length != 0) {
         output.WriteRawTag(10);
@@ -335,6 +364,7 @@
       }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public int CalculateSize() {
       int size = 0;
       if (Name.Length != 0) {
@@ -343,6 +373,7 @@
       return size;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void MergeFrom(GaugeRequest other) {
       if (other == null) {
         return;
@@ -352,6 +383,7 @@
       }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void MergeFrom(pb::CodedInputStream input) {
       uint tag;
       while ((tag = input.ReadTag()) != 0) {
@@ -369,36 +401,43 @@
 
   }
 
-  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
   public sealed partial class EmptyMessage : pb::IMessage<EmptyMessage> {
     private static readonly pb::MessageParser<EmptyMessage> _parser = new pb::MessageParser<EmptyMessage>(() => new EmptyMessage());
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pb::MessageParser<EmptyMessage> Parser { get { return _parser; } }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pbr::MessageDescriptor Descriptor {
       get { return global::Grpc.Testing.MetricsReflection.Descriptor.MessageTypes[2]; }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     pbr::MessageDescriptor pb::IMessage.Descriptor {
       get { return Descriptor; }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public EmptyMessage() {
       OnConstruction();
     }
 
     partial void OnConstruction();
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public EmptyMessage(EmptyMessage other) : this() {
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public EmptyMessage Clone() {
       return new EmptyMessage(this);
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override bool Equals(object other) {
       return Equals(other as EmptyMessage);
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public bool Equals(EmptyMessage other) {
       if (ReferenceEquals(other, null)) {
         return false;
@@ -409,29 +448,35 @@
       return true;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override int GetHashCode() {
       int hash = 1;
       return hash;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override string ToString() {
       return pb::JsonFormatter.ToDiagnosticString(this);
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void WriteTo(pb::CodedOutputStream output) {
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public int CalculateSize() {
       int size = 0;
       return size;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void MergeFrom(EmptyMessage other) {
       if (other == null) {
         return;
       }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void MergeFrom(pb::CodedInputStream input) {
       uint tag;
       while ((tag = input.ReadTag()) != 0) {
diff --git a/src/csharp/Grpc.IntegrationTesting/MetricsGrpc.cs b/src/csharp/Grpc.IntegrationTesting/MetricsGrpc.cs
index 040798e..bcd7e3c 100644
--- a/src/csharp/Grpc.IntegrationTesting/MetricsGrpc.cs
+++ b/src/csharp/Grpc.IntegrationTesting/MetricsGrpc.cs
@@ -161,6 +161,7 @@
       {
         return CallInvoker.AsyncUnaryCall(__Method_GetGauge, null, options, request);
       }
+      /// <summary>Creates a new instance of client from given <c>ClientBaseConfiguration</c>.</summary>
       protected override MetricsServiceClient NewInstance(ClientBaseConfiguration configuration)
       {
         return new MetricsServiceClient(configuration);
diff --git a/src/csharp/Grpc.IntegrationTesting/Payloads.cs b/src/csharp/Grpc.IntegrationTesting/Payloads.cs
index 3ad7a44..7aef35c 100644
--- a/src/csharp/Grpc.IntegrationTesting/Payloads.cs
+++ b/src/csharp/Grpc.IntegrationTesting/Payloads.cs
@@ -10,7 +10,6 @@
 namespace Grpc.Testing {
 
   /// <summary>Holder for reflection information generated from src/proto/grpc/testing/payloads.proto</summary>
-  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
   public static partial class PayloadsReflection {
 
     #region Descriptor
@@ -45,30 +44,35 @@
 
   }
   #region Messages
-  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
   public sealed partial class ByteBufferParams : pb::IMessage<ByteBufferParams> {
     private static readonly pb::MessageParser<ByteBufferParams> _parser = new pb::MessageParser<ByteBufferParams>(() => new ByteBufferParams());
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pb::MessageParser<ByteBufferParams> Parser { get { return _parser; } }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pbr::MessageDescriptor Descriptor {
       get { return global::Grpc.Testing.PayloadsReflection.Descriptor.MessageTypes[0]; }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     pbr::MessageDescriptor pb::IMessage.Descriptor {
       get { return Descriptor; }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public ByteBufferParams() {
       OnConstruction();
     }
 
     partial void OnConstruction();
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public ByteBufferParams(ByteBufferParams other) : this() {
       reqSize_ = other.reqSize_;
       respSize_ = other.respSize_;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public ByteBufferParams Clone() {
       return new ByteBufferParams(this);
     }
@@ -76,6 +80,7 @@
     /// <summary>Field number for the "req_size" field.</summary>
     public const int ReqSizeFieldNumber = 1;
     private int reqSize_;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public int ReqSize {
       get { return reqSize_; }
       set {
@@ -86,6 +91,7 @@
     /// <summary>Field number for the "resp_size" field.</summary>
     public const int RespSizeFieldNumber = 2;
     private int respSize_;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public int RespSize {
       get { return respSize_; }
       set {
@@ -93,10 +99,12 @@
       }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override bool Equals(object other) {
       return Equals(other as ByteBufferParams);
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public bool Equals(ByteBufferParams other) {
       if (ReferenceEquals(other, null)) {
         return false;
@@ -109,6 +117,7 @@
       return true;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override int GetHashCode() {
       int hash = 1;
       if (ReqSize != 0) hash ^= ReqSize.GetHashCode();
@@ -116,10 +125,12 @@
       return hash;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override string ToString() {
       return pb::JsonFormatter.ToDiagnosticString(this);
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void WriteTo(pb::CodedOutputStream output) {
       if (ReqSize != 0) {
         output.WriteRawTag(8);
@@ -131,6 +142,7 @@
       }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public int CalculateSize() {
       int size = 0;
       if (ReqSize != 0) {
@@ -142,6 +154,7 @@
       return size;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void MergeFrom(ByteBufferParams other) {
       if (other == null) {
         return;
@@ -154,6 +167,7 @@
       }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void MergeFrom(pb::CodedInputStream input) {
       uint tag;
       while ((tag = input.ReadTag()) != 0) {
@@ -175,30 +189,35 @@
 
   }
 
-  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
   public sealed partial class SimpleProtoParams : pb::IMessage<SimpleProtoParams> {
     private static readonly pb::MessageParser<SimpleProtoParams> _parser = new pb::MessageParser<SimpleProtoParams>(() => new SimpleProtoParams());
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pb::MessageParser<SimpleProtoParams> Parser { get { return _parser; } }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pbr::MessageDescriptor Descriptor {
       get { return global::Grpc.Testing.PayloadsReflection.Descriptor.MessageTypes[1]; }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     pbr::MessageDescriptor pb::IMessage.Descriptor {
       get { return Descriptor; }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public SimpleProtoParams() {
       OnConstruction();
     }
 
     partial void OnConstruction();
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public SimpleProtoParams(SimpleProtoParams other) : this() {
       reqSize_ = other.reqSize_;
       respSize_ = other.respSize_;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public SimpleProtoParams Clone() {
       return new SimpleProtoParams(this);
     }
@@ -206,6 +225,7 @@
     /// <summary>Field number for the "req_size" field.</summary>
     public const int ReqSizeFieldNumber = 1;
     private int reqSize_;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public int ReqSize {
       get { return reqSize_; }
       set {
@@ -216,6 +236,7 @@
     /// <summary>Field number for the "resp_size" field.</summary>
     public const int RespSizeFieldNumber = 2;
     private int respSize_;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public int RespSize {
       get { return respSize_; }
       set {
@@ -223,10 +244,12 @@
       }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override bool Equals(object other) {
       return Equals(other as SimpleProtoParams);
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public bool Equals(SimpleProtoParams other) {
       if (ReferenceEquals(other, null)) {
         return false;
@@ -239,6 +262,7 @@
       return true;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override int GetHashCode() {
       int hash = 1;
       if (ReqSize != 0) hash ^= ReqSize.GetHashCode();
@@ -246,10 +270,12 @@
       return hash;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override string ToString() {
       return pb::JsonFormatter.ToDiagnosticString(this);
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void WriteTo(pb::CodedOutputStream output) {
       if (ReqSize != 0) {
         output.WriteRawTag(8);
@@ -261,6 +287,7 @@
       }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public int CalculateSize() {
       int size = 0;
       if (ReqSize != 0) {
@@ -272,6 +299,7 @@
       return size;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void MergeFrom(SimpleProtoParams other) {
       if (other == null) {
         return;
@@ -284,6 +312,7 @@
       }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void MergeFrom(pb::CodedInputStream input) {
       uint tag;
       while ((tag = input.ReadTag()) != 0) {
@@ -309,36 +338,43 @@
   ///  TODO (vpai): Fill this in once the details of complex, representative
   ///               protos are decided
   /// </summary>
-  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
   public sealed partial class ComplexProtoParams : pb::IMessage<ComplexProtoParams> {
     private static readonly pb::MessageParser<ComplexProtoParams> _parser = new pb::MessageParser<ComplexProtoParams>(() => new ComplexProtoParams());
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pb::MessageParser<ComplexProtoParams> Parser { get { return _parser; } }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pbr::MessageDescriptor Descriptor {
       get { return global::Grpc.Testing.PayloadsReflection.Descriptor.MessageTypes[2]; }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     pbr::MessageDescriptor pb::IMessage.Descriptor {
       get { return Descriptor; }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public ComplexProtoParams() {
       OnConstruction();
     }
 
     partial void OnConstruction();
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public ComplexProtoParams(ComplexProtoParams other) : this() {
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public ComplexProtoParams Clone() {
       return new ComplexProtoParams(this);
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override bool Equals(object other) {
       return Equals(other as ComplexProtoParams);
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public bool Equals(ComplexProtoParams other) {
       if (ReferenceEquals(other, null)) {
         return false;
@@ -349,29 +385,35 @@
       return true;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override int GetHashCode() {
       int hash = 1;
       return hash;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override string ToString() {
       return pb::JsonFormatter.ToDiagnosticString(this);
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void WriteTo(pb::CodedOutputStream output) {
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public int CalculateSize() {
       int size = 0;
       return size;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void MergeFrom(ComplexProtoParams other) {
       if (other == null) {
         return;
       }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void MergeFrom(pb::CodedInputStream input) {
       uint tag;
       while ((tag = input.ReadTag()) != 0) {
@@ -385,25 +427,29 @@
 
   }
 
-  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
   public sealed partial class PayloadConfig : pb::IMessage<PayloadConfig> {
     private static readonly pb::MessageParser<PayloadConfig> _parser = new pb::MessageParser<PayloadConfig>(() => new PayloadConfig());
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pb::MessageParser<PayloadConfig> Parser { get { return _parser; } }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pbr::MessageDescriptor Descriptor {
       get { return global::Grpc.Testing.PayloadsReflection.Descriptor.MessageTypes[3]; }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     pbr::MessageDescriptor pb::IMessage.Descriptor {
       get { return Descriptor; }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public PayloadConfig() {
       OnConstruction();
     }
 
     partial void OnConstruction();
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public PayloadConfig(PayloadConfig other) : this() {
       switch (other.PayloadCase) {
         case PayloadOneofCase.BytebufParams:
@@ -419,12 +465,14 @@
 
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public PayloadConfig Clone() {
       return new PayloadConfig(this);
     }
 
     /// <summary>Field number for the "bytebuf_params" field.</summary>
     public const int BytebufParamsFieldNumber = 1;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public global::Grpc.Testing.ByteBufferParams BytebufParams {
       get { return payloadCase_ == PayloadOneofCase.BytebufParams ? (global::Grpc.Testing.ByteBufferParams) payload_ : null; }
       set {
@@ -435,6 +483,7 @@
 
     /// <summary>Field number for the "simple_params" field.</summary>
     public const int SimpleParamsFieldNumber = 2;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public global::Grpc.Testing.SimpleProtoParams SimpleParams {
       get { return payloadCase_ == PayloadOneofCase.SimpleParams ? (global::Grpc.Testing.SimpleProtoParams) payload_ : null; }
       set {
@@ -445,6 +494,7 @@
 
     /// <summary>Field number for the "complex_params" field.</summary>
     public const int ComplexParamsFieldNumber = 3;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public global::Grpc.Testing.ComplexProtoParams ComplexParams {
       get { return payloadCase_ == PayloadOneofCase.ComplexParams ? (global::Grpc.Testing.ComplexProtoParams) payload_ : null; }
       set {
@@ -462,19 +512,23 @@
       ComplexParams = 3,
     }
     private PayloadOneofCase payloadCase_ = PayloadOneofCase.None;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public PayloadOneofCase PayloadCase {
       get { return payloadCase_; }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void ClearPayload() {
       payloadCase_ = PayloadOneofCase.None;
       payload_ = null;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override bool Equals(object other) {
       return Equals(other as PayloadConfig);
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public bool Equals(PayloadConfig other) {
       if (ReferenceEquals(other, null)) {
         return false;
@@ -489,6 +543,7 @@
       return true;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override int GetHashCode() {
       int hash = 1;
       if (payloadCase_ == PayloadOneofCase.BytebufParams) hash ^= BytebufParams.GetHashCode();
@@ -498,10 +553,12 @@
       return hash;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override string ToString() {
       return pb::JsonFormatter.ToDiagnosticString(this);
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void WriteTo(pb::CodedOutputStream output) {
       if (payloadCase_ == PayloadOneofCase.BytebufParams) {
         output.WriteRawTag(10);
@@ -517,6 +574,7 @@
       }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public int CalculateSize() {
       int size = 0;
       if (payloadCase_ == PayloadOneofCase.BytebufParams) {
@@ -531,6 +589,7 @@
       return size;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void MergeFrom(PayloadConfig other) {
       if (other == null) {
         return;
@@ -549,6 +608,7 @@
 
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void MergeFrom(pb::CodedInputStream input) {
       uint tag;
       while ((tag = input.ReadTag()) != 0) {
diff --git a/src/csharp/Grpc.IntegrationTesting/Services.cs b/src/csharp/Grpc.IntegrationTesting/Services.cs
index e10b45c..bf36a02 100644
--- a/src/csharp/Grpc.IntegrationTesting/Services.cs
+++ b/src/csharp/Grpc.IntegrationTesting/Services.cs
@@ -10,7 +10,6 @@
 namespace Grpc.Testing {
 
   /// <summary>Holder for reflection information generated from src/proto/grpc/testing/services.proto</summary>
-  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
   public static partial class ServicesReflection {
 
     #region Descriptor
diff --git a/src/csharp/Grpc.IntegrationTesting/ServicesGrpc.cs b/src/csharp/Grpc.IntegrationTesting/ServicesGrpc.cs
index e205dea..848dd04 100644
--- a/src/csharp/Grpc.IntegrationTesting/ServicesGrpc.cs
+++ b/src/csharp/Grpc.IntegrationTesting/ServicesGrpc.cs
@@ -161,6 +161,7 @@
       {
         return CallInvoker.AsyncDuplexStreamingCall(__Method_StreamingCall, null, options);
       }
+      /// <summary>Creates a new instance of client from given <c>ClientBaseConfiguration</c>.</summary>
       protected override BenchmarkServiceClient NewInstance(ClientBaseConfiguration configuration)
       {
         return new BenchmarkServiceClient(configuration);
@@ -396,6 +397,7 @@
       {
         return CallInvoker.AsyncUnaryCall(__Method_QuitWorker, null, options, request);
       }
+      /// <summary>Creates a new instance of client from given <c>ClientBaseConfiguration</c>.</summary>
       protected override WorkerServiceClient NewInstance(ClientBaseConfiguration configuration)
       {
         return new WorkerServiceClient(configuration);
diff --git a/src/csharp/Grpc.IntegrationTesting/Stats.cs b/src/csharp/Grpc.IntegrationTesting/Stats.cs
index 304d676..0ae77cf 100644
--- a/src/csharp/Grpc.IntegrationTesting/Stats.cs
+++ b/src/csharp/Grpc.IntegrationTesting/Stats.cs
@@ -10,7 +10,6 @@
 namespace Grpc.Testing {
 
   /// <summary>Holder for reflection information generated from src/proto/grpc/testing/stats.proto</summary>
-  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
   public static partial class StatsReflection {
 
     #region Descriptor
@@ -46,31 +45,36 @@
 
   }
   #region Messages
-  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
   public sealed partial class ServerStats : pb::IMessage<ServerStats> {
     private static readonly pb::MessageParser<ServerStats> _parser = new pb::MessageParser<ServerStats>(() => new ServerStats());
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pb::MessageParser<ServerStats> Parser { get { return _parser; } }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pbr::MessageDescriptor Descriptor {
       get { return global::Grpc.Testing.StatsReflection.Descriptor.MessageTypes[0]; }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     pbr::MessageDescriptor pb::IMessage.Descriptor {
       get { return Descriptor; }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public ServerStats() {
       OnConstruction();
     }
 
     partial void OnConstruction();
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public ServerStats(ServerStats other) : this() {
       timeElapsed_ = other.timeElapsed_;
       timeUser_ = other.timeUser_;
       timeSystem_ = other.timeSystem_;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public ServerStats Clone() {
       return new ServerStats(this);
     }
@@ -81,6 +85,7 @@
     /// <summary>
     ///  wall clock time change in seconds since last reset
     /// </summary>
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public double TimeElapsed {
       get { return timeElapsed_; }
       set {
@@ -94,6 +99,7 @@
     /// <summary>
     ///  change in user time (in seconds) used by the server since last reset
     /// </summary>
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public double TimeUser {
       get { return timeUser_; }
       set {
@@ -108,6 +114,7 @@
     ///  change in server time (in seconds) used by the server process and all
     ///  threads since last reset
     /// </summary>
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public double TimeSystem {
       get { return timeSystem_; }
       set {
@@ -115,10 +122,12 @@
       }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override bool Equals(object other) {
       return Equals(other as ServerStats);
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public bool Equals(ServerStats other) {
       if (ReferenceEquals(other, null)) {
         return false;
@@ -132,6 +141,7 @@
       return true;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override int GetHashCode() {
       int hash = 1;
       if (TimeElapsed != 0D) hash ^= TimeElapsed.GetHashCode();
@@ -140,10 +150,12 @@
       return hash;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override string ToString() {
       return pb::JsonFormatter.ToDiagnosticString(this);
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void WriteTo(pb::CodedOutputStream output) {
       if (TimeElapsed != 0D) {
         output.WriteRawTag(9);
@@ -159,6 +171,7 @@
       }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public int CalculateSize() {
       int size = 0;
       if (TimeElapsed != 0D) {
@@ -173,6 +186,7 @@
       return size;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void MergeFrom(ServerStats other) {
       if (other == null) {
         return;
@@ -188,6 +202,7 @@
       }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void MergeFrom(pb::CodedInputStream input) {
       uint tag;
       while ((tag = input.ReadTag()) != 0) {
@@ -216,30 +231,35 @@
   /// <summary>
   ///  Histogram params based on grpc/support/histogram.c
   /// </summary>
-  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
   public sealed partial class HistogramParams : pb::IMessage<HistogramParams> {
     private static readonly pb::MessageParser<HistogramParams> _parser = new pb::MessageParser<HistogramParams>(() => new HistogramParams());
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pb::MessageParser<HistogramParams> Parser { get { return _parser; } }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pbr::MessageDescriptor Descriptor {
       get { return global::Grpc.Testing.StatsReflection.Descriptor.MessageTypes[1]; }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     pbr::MessageDescriptor pb::IMessage.Descriptor {
       get { return Descriptor; }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public HistogramParams() {
       OnConstruction();
     }
 
     partial void OnConstruction();
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public HistogramParams(HistogramParams other) : this() {
       resolution_ = other.resolution_;
       maxPossible_ = other.maxPossible_;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public HistogramParams Clone() {
       return new HistogramParams(this);
     }
@@ -250,6 +270,7 @@
     /// <summary>
     ///  first bucket is [0, 1 + resolution)
     /// </summary>
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public double Resolution {
       get { return resolution_; }
       set {
@@ -263,6 +284,7 @@
     /// <summary>
     ///  use enough buckets to allow this value
     /// </summary>
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public double MaxPossible {
       get { return maxPossible_; }
       set {
@@ -270,10 +292,12 @@
       }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override bool Equals(object other) {
       return Equals(other as HistogramParams);
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public bool Equals(HistogramParams other) {
       if (ReferenceEquals(other, null)) {
         return false;
@@ -286,6 +310,7 @@
       return true;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override int GetHashCode() {
       int hash = 1;
       if (Resolution != 0D) hash ^= Resolution.GetHashCode();
@@ -293,10 +318,12 @@
       return hash;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override string ToString() {
       return pb::JsonFormatter.ToDiagnosticString(this);
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void WriteTo(pb::CodedOutputStream output) {
       if (Resolution != 0D) {
         output.WriteRawTag(9);
@@ -308,6 +335,7 @@
       }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public int CalculateSize() {
       int size = 0;
       if (Resolution != 0D) {
@@ -319,6 +347,7 @@
       return size;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void MergeFrom(HistogramParams other) {
       if (other == null) {
         return;
@@ -331,6 +360,7 @@
       }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void MergeFrom(pb::CodedInputStream input) {
       uint tag;
       while ((tag = input.ReadTag()) != 0) {
@@ -355,25 +385,29 @@
   /// <summary>
   ///  Histogram data based on grpc/support/histogram.c
   /// </summary>
-  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
   public sealed partial class HistogramData : pb::IMessage<HistogramData> {
     private static readonly pb::MessageParser<HistogramData> _parser = new pb::MessageParser<HistogramData>(() => new HistogramData());
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pb::MessageParser<HistogramData> Parser { get { return _parser; } }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pbr::MessageDescriptor Descriptor {
       get { return global::Grpc.Testing.StatsReflection.Descriptor.MessageTypes[2]; }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     pbr::MessageDescriptor pb::IMessage.Descriptor {
       get { return Descriptor; }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public HistogramData() {
       OnConstruction();
     }
 
     partial void OnConstruction();
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public HistogramData(HistogramData other) : this() {
       bucket_ = other.bucket_.Clone();
       minSeen_ = other.minSeen_;
@@ -383,6 +417,7 @@
       count_ = other.count_;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public HistogramData Clone() {
       return new HistogramData(this);
     }
@@ -392,6 +427,7 @@
     private static readonly pb::FieldCodec<uint> _repeated_bucket_codec
         = pb::FieldCodec.ForUInt32(10);
     private readonly pbc::RepeatedField<uint> bucket_ = new pbc::RepeatedField<uint>();
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public pbc::RepeatedField<uint> Bucket {
       get { return bucket_; }
     }
@@ -399,6 +435,7 @@
     /// <summary>Field number for the "min_seen" field.</summary>
     public const int MinSeenFieldNumber = 2;
     private double minSeen_;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public double MinSeen {
       get { return minSeen_; }
       set {
@@ -409,6 +446,7 @@
     /// <summary>Field number for the "max_seen" field.</summary>
     public const int MaxSeenFieldNumber = 3;
     private double maxSeen_;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public double MaxSeen {
       get { return maxSeen_; }
       set {
@@ -419,6 +457,7 @@
     /// <summary>Field number for the "sum" field.</summary>
     public const int SumFieldNumber = 4;
     private double sum_;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public double Sum {
       get { return sum_; }
       set {
@@ -429,6 +468,7 @@
     /// <summary>Field number for the "sum_of_squares" field.</summary>
     public const int SumOfSquaresFieldNumber = 5;
     private double sumOfSquares_;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public double SumOfSquares {
       get { return sumOfSquares_; }
       set {
@@ -439,6 +479,7 @@
     /// <summary>Field number for the "count" field.</summary>
     public const int CountFieldNumber = 6;
     private double count_;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public double Count {
       get { return count_; }
       set {
@@ -446,10 +487,12 @@
       }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override bool Equals(object other) {
       return Equals(other as HistogramData);
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public bool Equals(HistogramData other) {
       if (ReferenceEquals(other, null)) {
         return false;
@@ -466,6 +509,7 @@
       return true;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override int GetHashCode() {
       int hash = 1;
       hash ^= bucket_.GetHashCode();
@@ -477,10 +521,12 @@
       return hash;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override string ToString() {
       return pb::JsonFormatter.ToDiagnosticString(this);
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void WriteTo(pb::CodedOutputStream output) {
       bucket_.WriteTo(output, _repeated_bucket_codec);
       if (MinSeen != 0D) {
@@ -505,6 +551,7 @@
       }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public int CalculateSize() {
       int size = 0;
       size += bucket_.CalculateSize(_repeated_bucket_codec);
@@ -526,6 +573,7 @@
       return size;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void MergeFrom(HistogramData other) {
       if (other == null) {
         return;
@@ -548,6 +596,7 @@
       }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void MergeFrom(pb::CodedInputStream input) {
       uint tag;
       while ((tag = input.ReadTag()) != 0) {
@@ -586,25 +635,29 @@
 
   }
 
-  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
   public sealed partial class ClientStats : pb::IMessage<ClientStats> {
     private static readonly pb::MessageParser<ClientStats> _parser = new pb::MessageParser<ClientStats>(() => new ClientStats());
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pb::MessageParser<ClientStats> Parser { get { return _parser; } }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pbr::MessageDescriptor Descriptor {
       get { return global::Grpc.Testing.StatsReflection.Descriptor.MessageTypes[3]; }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     pbr::MessageDescriptor pb::IMessage.Descriptor {
       get { return Descriptor; }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public ClientStats() {
       OnConstruction();
     }
 
     partial void OnConstruction();
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public ClientStats(ClientStats other) : this() {
       Latencies = other.latencies_ != null ? other.Latencies.Clone() : null;
       timeElapsed_ = other.timeElapsed_;
@@ -612,6 +665,7 @@
       timeSystem_ = other.timeSystem_;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public ClientStats Clone() {
       return new ClientStats(this);
     }
@@ -622,6 +676,7 @@
     /// <summary>
     ///  Latency histogram. Data points are in nanoseconds.
     /// </summary>
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public global::Grpc.Testing.HistogramData Latencies {
       get { return latencies_; }
       set {
@@ -635,6 +690,7 @@
     /// <summary>
     ///  See ServerStats for details.
     /// </summary>
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public double TimeElapsed {
       get { return timeElapsed_; }
       set {
@@ -645,6 +701,7 @@
     /// <summary>Field number for the "time_user" field.</summary>
     public const int TimeUserFieldNumber = 3;
     private double timeUser_;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public double TimeUser {
       get { return timeUser_; }
       set {
@@ -655,6 +712,7 @@
     /// <summary>Field number for the "time_system" field.</summary>
     public const int TimeSystemFieldNumber = 4;
     private double timeSystem_;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public double TimeSystem {
       get { return timeSystem_; }
       set {
@@ -662,10 +720,12 @@
       }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override bool Equals(object other) {
       return Equals(other as ClientStats);
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public bool Equals(ClientStats other) {
       if (ReferenceEquals(other, null)) {
         return false;
@@ -680,6 +740,7 @@
       return true;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override int GetHashCode() {
       int hash = 1;
       if (latencies_ != null) hash ^= Latencies.GetHashCode();
@@ -689,10 +750,12 @@
       return hash;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override string ToString() {
       return pb::JsonFormatter.ToDiagnosticString(this);
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void WriteTo(pb::CodedOutputStream output) {
       if (latencies_ != null) {
         output.WriteRawTag(10);
@@ -712,6 +775,7 @@
       }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public int CalculateSize() {
       int size = 0;
       if (latencies_ != null) {
@@ -729,6 +793,7 @@
       return size;
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void MergeFrom(ClientStats other) {
       if (other == null) {
         return;
@@ -750,6 +815,7 @@
       }
     }
 
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void MergeFrom(pb::CodedInputStream input) {
       uint tag;
       while ((tag = input.ReadTag()) != 0) {
diff --git a/src/csharp/Grpc.IntegrationTesting/Test.cs b/src/csharp/Grpc.IntegrationTesting/Test.cs
index 9258dc1..88c2b8a 100644
--- a/src/csharp/Grpc.IntegrationTesting/Test.cs
+++ b/src/csharp/Grpc.IntegrationTesting/Test.cs
@@ -10,7 +10,6 @@
 namespace Grpc.Testing {
 
   /// <summary>Holder for reflection information generated from src/proto/grpc/testing/test.proto</summary>
-  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
   public static partial class TestReflection {
 
     #region Descriptor
diff --git a/src/csharp/Grpc.IntegrationTesting/TestGrpc.cs b/src/csharp/Grpc.IntegrationTesting/TestGrpc.cs
index 3e149da..61f2ed4 100644
--- a/src/csharp/Grpc.IntegrationTesting/TestGrpc.cs
+++ b/src/csharp/Grpc.IntegrationTesting/TestGrpc.cs
@@ -314,6 +314,7 @@
       {
         return CallInvoker.AsyncDuplexStreamingCall(__Method_HalfDuplexCall, null, options);
       }
+      /// <summary>Creates a new instance of client from given <c>ClientBaseConfiguration</c>.</summary>
       protected override TestServiceClient NewInstance(ClientBaseConfiguration configuration)
       {
         return new TestServiceClient(configuration);
@@ -420,6 +421,7 @@
       {
         return CallInvoker.AsyncUnaryCall(__Method_UnimplementedCall, null, options, request);
       }
+      /// <summary>Creates a new instance of client from given <c>ClientBaseConfiguration</c>.</summary>
       protected override UnimplementedServiceClient NewInstance(ClientBaseConfiguration configuration)
       {
         return new UnimplementedServiceClient(configuration);
@@ -535,6 +537,7 @@
       {
         return CallInvoker.AsyncUnaryCall(__Method_Stop, null, options, request);
       }
+      /// <summary>Creates a new instance of client from given <c>ClientBaseConfiguration</c>.</summary>
       protected override ReconnectServiceClient NewInstance(ClientBaseConfiguration configuration)
       {
         return new ReconnectServiceClient(configuration);
diff --git a/src/csharp/README.md b/src/csharp/README.md
index 18d5945..0405ff8 100644
--- a/src/csharp/README.md
+++ b/src/csharp/README.md
@@ -4,10 +4,13 @@
 
 A C# implementation of gRPC.
 
-Status
-------
+SUPPORTED PLATFORMS
+------------------
 
-Beta
+- .NET Framework 4.5+ (Windows)
+- [.NET Core](https://dotnet.github.io/) on Linux, Windows and Mac OS X (starting from version 1.0.1)
+- Mono 4+ on Linux, Windows and Mac OS X
+
 
 PREREQUISITES
 --------------
@@ -16,6 +19,7 @@
 - Linux: Mono 4+, MonoDevelop 5.9+ (with NuGet add-in installed)
 - Mac OS X: Xamarin Studio 5.9+
 
+
 HOW TO USE
 --------------
 
@@ -69,12 +73,6 @@
 tools/run_tests/run_tests.py -l csharp
 ```
 
-ON .NET CORE SUPPORT
-------------------
-
-We are committed to providing full support for [.NET Core](https://dotnet.github.io/) in near future,
-but currently, the support is for .NET Core is experimental/work-in-progress.
-
 DOCUMENTATION
 -------------
 - [API Reference][]
@@ -102,9 +100,7 @@
 THE NATIVE DEPENDENCY
 ---------------
 
-Internally, gRPC C# uses a native library written in C (gRPC C core) and invokes its functionality via P/Invoke. `grpc_csharp_ext` library is a native extension library that facilitates this by wrapping some C core API into a form that's more digestible for P/Invoke.
-
-Prior to version 0.13, installing `grpc_csharp_ext` was required to make gRPC work on Linux and MacOS. Starting with version 0.13, we have improved the packaging story significantly and precompiled versions of the native library for all supported platforms are now shipped with the NuGet package. Just installing the `Grpc` NuGet package should be the only step needed to use gRPC C#, regardless of your platform (Windows, Linux or Mac) and the bitness (32 or 64bit).
+Internally, gRPC C# uses a native library written in C (gRPC C core) and invokes its functionality via P/Invoke. The fact that a native library is used should be fully transparent to the users and just installing the `Grpc.Core` NuGet package is the only step needed to use gRPC C# on all supported platforms.
 
 [API Reference]: http://www.grpc.io/grpc/csharp/
 [Helloworld Example]: ../../examples/csharp/helloworld
diff --git a/src/node/README.md b/src/node/README.md
index 9eafce9..4b90664 100644
--- a/src/node/README.md
+++ b/src/node/README.md
@@ -1,9 +1,6 @@
 [![npm](https://img.shields.io/npm/v/grpc.svg)](https://www.npmjs.com/package/grpc)
 # Node.js gRPC Library
 
-## Status
-Beta
-
 ## PREREQUISITES
 - `node`: This requires `node` to be installed, version `0.12` or above. If you instead have the `nodejs` executable on Debian, you should install the [`nodejs-legacy`](https://packages.debian.org/sid/nodejs-legacy) package.
 
diff --git a/src/objective-c/tests/InteropTests.m b/src/objective-c/tests/InteropTests.m
index 44f22c9..9804734 100644
--- a/src/objective-c/tests/InteropTests.m
+++ b/src/objective-c/tests/InteropTests.m
@@ -92,20 +92,21 @@
   return 0;
 }
 
++ (void)setUp {
+#ifdef GRPC_COMPILE_WITH_CRONET
+  // Cronet setup
+  [Cronet setHttp2Enabled:YES];
+  [Cronet start];
+  [GRPCCall useCronetWithEngine:[Cronet getGlobalEngine]];
+#endif
+}
+
 - (void)setUp {
   self.continueAfterFailure = NO;
 
   [GRPCCall resetHostSettings];
 
   _service = self.class.host ? [RMTTestService serviceWithHost:self.class.host] : nil;
-#ifdef GRPC_COMPILE_WITH_CRONET
-  if (cronetEngine == NULL) {
-    // Cronet setup
-    [Cronet setHttp2Enabled:YES];
-    [Cronet start];
-    [GRPCCall useCronetWithEngine:[Cronet getGlobalEngine]];
-  }
-#endif
 }
 
 - (void)testEmptyUnaryRPC {
diff --git a/src/php/README.md b/src/php/README.md
index 0e5b4de..1b15768 100644
--- a/src/php/README.md
+++ b/src/php/README.md
@@ -4,10 +4,6 @@
 This directory contains source code for PHP implementation of gRPC layered on
 shared C library.
 
-#Status
-
-GA
-
 ## Environment
 
 **Prerequisite:**
diff --git a/src/proto/grpc/testing/test.proto b/src/proto/grpc/testing/test.proto
index 84369db..b52c4cb 100644
--- a/src/proto/grpc/testing/test.proto
+++ b/src/proto/grpc/testing/test.proto
@@ -47,6 +47,11 @@
   // One request followed by one response.
   rpc UnaryCall(SimpleRequest) returns (SimpleResponse);
 
+  // One request followed by one response. Response has cache control
+  // headers set such that a caching HTTP proxy (such as GFE) can
+  // satisfy subsequent requests.
+  rpc CacheableUnaryCall(SimpleRequest) returns (SimpleResponse);
+
   // One request followed by a sequence of responses (streamed download).
   // The server returns the payload with client desired type and sizes.
   rpc StreamingOutputCall(StreamingOutputCallRequest)
diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi
index ad20c94..9560fad 100644
--- a/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi
+++ b/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi
@@ -173,10 +173,14 @@
     GRPC_ARG_INTEGER
     GRPC_ARG_POINTER
 
-  ctypedef struct grpc_arg_value_pointer:
-    void *address "p"
+  ctypedef struct grpc_arg_pointer_vtable:
     void *(*copy)(void *)
     void (*destroy)(void *)
+    int (*cmp)(void *, void *)
+
+  ctypedef struct grpc_arg_value_pointer:
+    void *address "p"
+    grpc_arg_pointer_vtable *vtable
 
   union grpc_arg_value:
     char *string
diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/records.pxd.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/records.pxd.pxi
index 96c5b02..00ec91b 100644
--- a/src/python/grpcio/grpc/_cython/_cygrpc/records.pxd.pxi
+++ b/src/python/grpcio/grpc/_cython/_cygrpc/records.pxd.pxi
@@ -84,6 +84,7 @@
 cdef class ChannelArg:
 
   cdef grpc_arg c_arg
+  cdef grpc_arg_pointer_vtable ptr_vtable
   cdef readonly object key, value
 
 
diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/records.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/records.pyx.pxi
index 5a11a08..8a4eef4 100644
--- a/src/python/grpcio/grpc/_cython/_cygrpc/records.pyx.pxi
+++ b/src/python/grpcio/grpc/_cython/_cygrpc/records.pyx.pxi
@@ -27,6 +27,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.
 
+from libc.stdint cimport intptr_t
 
 class ConnectivityState:
   idle = GRPC_CHANNEL_IDLE
@@ -304,20 +305,49 @@
     self.c_pair.certificate_chain = self.certificate_chain
 
 
+
+cdef void* copy_ptr(void* ptr):
+  return ptr
+
+
+cdef void destroy_ptr(void* ptr):
+  pass
+
+
+cdef int compare_ptr(void* ptr1, void* ptr2):
+  if ptr1 < ptr2:
+    return -1
+  elif ptr1 > ptr2:
+    return 1
+  else:
+    return 0
+
+
 cdef class ChannelArg:
 
   def __cinit__(self, bytes key, value):
     self.key = key
+    self.value = value
     self.c_arg.key = self.key
     if isinstance(value, int):
-      self.value = value
       self.c_arg.type = GRPC_ARG_INTEGER
       self.c_arg.value.integer = self.value
     elif isinstance(value, bytes):
-      self.value = value
       self.c_arg.type = GRPC_ARG_STRING
       self.c_arg.value.string = self.value
+    elif hasattr(value, '__int__'):
+      # Pointer objects must override __int__() to return
+      # the underlying C address (Python ints are word size).  The
+      # lifecycle of the pointer is fixed to the lifecycle of the 
+      # python object wrapping it.
+      self.ptr_vtable.copy = &copy_ptr
+      self.ptr_vtable.destroy = &destroy_ptr
+      self.ptr_vtable.cmp = &compare_ptr
+      self.c_arg.type = GRPC_ARG_POINTER
+      self.c_arg.value.pointer.vtable = &self.ptr_vtable
+      self.c_arg.value.pointer.address = <void*>(<intptr_t>int(self.value))
     else:
+      # TODO Add supported pointer types to this message
       raise TypeError('Expected int or bytes, got {}'.format(type(value)))
 
 
diff --git a/src/python/grpcio_tests/tests/unit/_channel_args_test.py b/src/python/grpcio_tests/tests/unit/_channel_args_test.py
index 6a636d7..b46497a 100644
--- a/src/python/grpcio_tests/tests/unit/_channel_args_test.py
+++ b/src/python/grpcio_tests/tests/unit/_channel_args_test.py
@@ -33,11 +33,18 @@
 
 import grpc
 
+class TestPointerWrapper(object):
+
+  def __int__(self):
+    return 123456
+
+
 TEST_CHANNEL_ARGS = (
     ('arg1', b'bytes_val'),
     ('arg2', 'str_val'),
     ('arg3', 1),
     (b'arg4', 'str_val'),
+    ('arg6', TestPointerWrapper()),
 )
 
 
diff --git a/src/ruby/README.md b/src/ruby/README.md
index 67e94dd..f476fe7 100644
--- a/src/ruby/README.md
+++ b/src/ruby/README.md
@@ -4,11 +4,6 @@
 
 A Ruby implementation of gRPC.
 
-Status
-------
-
-Beta
-
 PREREQUISITES
 -------------
 
diff --git a/templates/tools/dockerfile/test/cxx_wheezy_x64/Dockerfile.template b/templates/tools/dockerfile/test/cxx_wheezy_x64/Dockerfile.template
index b6a3b0d..5c38e9a 100644
--- a/templates/tools/dockerfile/test/cxx_wheezy_x64/Dockerfile.template
+++ b/templates/tools/dockerfile/test/cxx_wheezy_x64/Dockerfile.template
@@ -41,6 +41,12 @@
     g++-4.4 ${'\\'}
     g++-4.4-multilib
 
+  # set up backport to allow installation of Git version > 1.7
+  RUN echo "deb http://http.debian.net/debian wheezy-backports main" \
+    >/etc/apt/sources.list.d/wheezy-backports.list
+  RUN apt-get update -qq
+  RUN apt-get -t wheezy-backports install -qq git
+  
   RUN wget ${openssl_fallback.base_uri + openssl_fallback.tarball}
 
   ENV POST_GIT_STEP tools/dockerfile/test/cxx_wheezy_x64/post-git-setup.sh
diff --git a/test/core/iomgr/tcp_server_posix_test.c b/test/core/iomgr/tcp_server_posix_test.c
index 6e2d1d0..6b1dd42 100644
--- a/test/core/iomgr/tcp_server_posix_test.c
+++ b/test/core/iomgr/tcp_server_posix_test.c
@@ -314,11 +314,10 @@
   GPR_ASSERT(grpc_tcp_server_port_fd(s, 0, 0) >= 0);
 
   grpc_tcp_server_unref(&exec_ctx, s);
+  grpc_exec_ctx_finish(&exec_ctx);
 
   /* Weak ref lost. */
   GPR_ASSERT(weak_ref.server == NULL);
-
-  grpc_exec_ctx_finish(&exec_ctx);
 }
 
 static void destroy_pollset(grpc_exec_ctx *exec_ctx, void *p,
diff --git a/test/core/iomgr/udp_server_test.c b/test/core/iomgr/udp_server_test.c
index 2a304275..71d2fb5 100644
--- a/test/core/iomgr/udp_server_test.c
+++ b/test/core/iomgr/udp_server_test.c
@@ -131,8 +131,9 @@
   grpc_udp_server_destroy(&exec_ctx, s, NULL);
   grpc_exec_ctx_finish(&exec_ctx);
 
-  /* The server had a single FD, which should have been orphaned. */
-  GPR_ASSERT(g_number_of_orphan_calls == 1);
+  /* The server had a single FD, which is orphaned once in *
+   * deactivated_all_ports, and once in grpc_udp_server_destroy. */
+  GPR_ASSERT(g_number_of_orphan_calls == 2);
 }
 
 static void test_receive(int number_of_clients) {
@@ -196,8 +197,9 @@
   grpc_udp_server_destroy(&exec_ctx, s, NULL);
   grpc_exec_ctx_finish(&exec_ctx);
 
-  /* The server had a single FD, which should have been orphaned. */
-  GPR_ASSERT(g_number_of_orphan_calls == 1);
+  /* The server had a single FD, which is orphaned once in *
+   * deactivated_all_ports, and once in grpc_udp_server_destroy. */
+  GPR_ASSERT(g_number_of_orphan_calls == 2);
 }
 
 static void destroy_pollset(grpc_exec_ctx *exec_ctx, void *p,
diff --git a/test/core/security/credentials_test.c b/test/core/security/credentials_test.c
index 7043953..2f8ffe4 100644
--- a/test/core/security/credentials_test.c
+++ b/test/core/security/credentials_test.c
@@ -46,6 +46,7 @@
 
 #include "src/core/lib/http/httpcli.h"
 #include "src/core/lib/security/credentials/composite/composite_credentials.h"
+#include "src/core/lib/security/credentials/fake/fake_credentials.h"
 #include "src/core/lib/security/credentials/google_default/google_default_credentials.h"
 #include "src/core/lib/security/credentials/jwt/jwt_credentials.h"
 #include "src/core/lib/security/credentials/oauth2/oauth2_credentials.h"
@@ -411,7 +412,7 @@
 static void test_channel_oauth2_composite_creds(void) {
   grpc_channel_args *new_args;
   grpc_channel_credentials_vtable vtable = {
-      NULL, check_channel_oauth2_create_security_connector};
+      NULL, check_channel_oauth2_create_security_connector, NULL};
   grpc_channel_credentials *channel_creds =
       grpc_mock_channel_credentials_create(&vtable);
   grpc_call_credentials *oauth2_creds =
@@ -495,7 +496,7 @@
 static void test_channel_oauth2_google_iam_composite_creds(void) {
   grpc_channel_args *new_args;
   grpc_channel_credentials_vtable vtable = {
-      NULL, check_channel_oauth2_google_iam_create_security_connector};
+      NULL, check_channel_oauth2_google_iam_create_security_connector, NULL};
   grpc_channel_credentials *channel_creds =
       grpc_mock_channel_credentials_create(&vtable);
   grpc_call_credentials *oauth2_creds =
@@ -1148,6 +1149,31 @@
 #endif
 }
 
+static void test_channel_creds_duplicate_without_call_creds(void) {
+  grpc_channel_credentials *channel_creds =
+      grpc_fake_transport_security_credentials_create();
+
+  grpc_channel_credentials *dup =
+      grpc_channel_credentials_duplicate_without_call_credentials(
+          channel_creds);
+  GPR_ASSERT(dup == channel_creds);
+  grpc_channel_credentials_unref(dup);
+
+  grpc_call_credentials *call_creds =
+      grpc_access_token_credentials_create("blah", NULL);
+  grpc_channel_credentials *composite_creds =
+      grpc_composite_channel_credentials_create(channel_creds, call_creds,
+                                                NULL);
+  grpc_call_credentials_unref(call_creds);
+  dup = grpc_channel_credentials_duplicate_without_call_credentials(
+      composite_creds);
+  GPR_ASSERT(dup == channel_creds);
+  grpc_channel_credentials_unref(dup);
+
+  grpc_channel_credentials_unref(channel_creds);
+  grpc_channel_credentials_unref(composite_creds);
+}
+
 int main(int argc, char **argv) {
   grpc_test_init(argc, argv);
   grpc_init();
@@ -1182,6 +1208,7 @@
   test_metadata_plugin_success();
   test_metadata_plugin_failure();
   test_get_well_known_google_credentials_file_path();
+  test_channel_creds_duplicate_without_call_creds();
   grpc_shutdown();
   return 0;
 }
diff --git a/test/cpp/interop/client.cc b/test/cpp/interop/client.cc
index 032b378..999be9d 100644
--- a/test/cpp/interop/client.cc
+++ b/test/cpp/interop/client.cc
@@ -149,6 +149,8 @@
     client.DoStatusWithMessage();
   } else if (FLAGS_test_case == "custom_metadata") {
     client.DoCustomMetadata();
+  } else if (FLAGS_test_case == "cacheable_unary") {
+    client.DoCacheableUnary();
   } else if (FLAGS_test_case == "all") {
     client.DoEmpty();
     client.DoLargeUnary();
@@ -166,6 +168,7 @@
     client.DoEmptyStream();
     client.DoStatusWithMessage();
     client.DoCustomMetadata();
+    client.DoCacheableUnary();
     // service_account_creds and jwt_token_creds can only run with ssl.
     if (FLAGS_use_tls) {
       grpc::string json_key = GetServiceAccountJsonKey();
@@ -177,6 +180,7 @@
     // compute_engine_creds only runs in GCE.
   } else {
     const char* testcases[] = {"all",
+                               "cacheable_unary",
                                "cancel_after_begin",
                                "cancel_after_first_response",
                                "client_compressed_streaming",
diff --git a/test/cpp/interop/interop_client.cc b/test/cpp/interop/interop_client.cc
index 6117878..e9a804c 100644
--- a/test/cpp/interop/interop_client.cc
+++ b/test/cpp/interop/interop_client.cc
@@ -846,6 +846,50 @@
   return true;
 }
 
+bool InteropClient::DoCacheableUnary() {
+  gpr_log(GPR_DEBUG, "Sending RPC with cacheable response");
+
+  // Create request with current timestamp
+  gpr_timespec ts = gpr_now(GPR_CLOCK_PRECISE);
+  std::string timestamp = std::to_string((long long unsigned)ts.tv_nsec);
+  SimpleRequest request;
+  request.mutable_payload()->set_body(timestamp.c_str(), timestamp.size());
+
+  // Request 1
+  ClientContext context1;
+  SimpleResponse response1;
+  context1.set_cacheable(true);
+  // Add fake user IP since some proxy's (GFE) won't cache requests from
+  // localhost.
+  context1.AddMetadata("x-user-ip", "1.2.3.4");
+  Status s1 =
+      serviceStub_.Get()->CacheableUnaryCall(&context1, request, &response1);
+  if (!AssertStatusOk(s1)) {
+    return false;
+  }
+  gpr_log(GPR_DEBUG, "response 1 payload: %s",
+          response1.payload().body().c_str());
+
+  // Request 2
+  ClientContext context2;
+  SimpleResponse response2;
+  context2.set_cacheable(true);
+  context2.AddMetadata("x-user-ip", "1.2.3.4");
+  Status s2 =
+      serviceStub_.Get()->CacheableUnaryCall(&context2, request, &response2);
+  if (!AssertStatusOk(s2)) {
+    return false;
+  }
+  gpr_log(GPR_DEBUG, "response 2 payload: %s",
+          response2.payload().body().c_str());
+
+  // Check that the body is same for both requests. It will be the same if the
+  // second response is a cached copy of the first response
+  GPR_ASSERT(response2.payload().body() == response1.payload().body());
+
+  return true;
+}
+
 bool InteropClient::DoCustomMetadata() {
   const grpc::string kEchoInitialMetadataKey("x-grpc-test-echo-initial");
   const grpc::string kInitialMetadataValue("test_initial_metadata_value");
diff --git a/test/cpp/interop/interop_client.h b/test/cpp/interop/interop_client.h
index eb886fc..1e89f09 100644
--- a/test/cpp/interop/interop_client.h
+++ b/test/cpp/interop/interop_client.h
@@ -79,6 +79,7 @@
   bool DoEmptyStream();
   bool DoStatusWithMessage();
   bool DoCustomMetadata();
+  bool DoCacheableUnary();
   // Auth tests.
   // username is a string containing the user email
   bool DoJwtTokenCreds(const grpc::string& username);
diff --git a/test/cpp/interop/interop_server.cc b/test/cpp/interop/interop_server.cc
index c05eb5d..58f20aa 100644
--- a/test/cpp/interop/interop_server.cc
+++ b/test/cpp/interop/interop_server.cc
@@ -47,6 +47,7 @@
 #include <grpc/support/log.h>
 #include <grpc/support/useful.h>
 
+#include "src/core/lib/support/string.h"
 #include "src/core/lib/transport/byte_stream.h"
 #include "src/proto/grpc/testing/empty.grpc.pb.h"
 #include "src/proto/grpc/testing/messages.grpc.pb.h"
@@ -153,6 +154,17 @@
     return Status::OK;
   }
 
+  // Response contains current timestamp. We ignore everything in the request.
+  Status CacheableUnaryCall(ServerContext* context,
+                            const SimpleRequest* request,
+                            SimpleResponse* response) {
+    gpr_timespec ts = gpr_now(GPR_CLOCK_PRECISE);
+    std::string timestamp = std::to_string((long long unsigned)ts.tv_nsec);
+    response->mutable_payload()->set_body(timestamp.c_str(), timestamp.size());
+    context->AddInitialMetadata("cache-control", "max-age=60, public");
+    return Status::OK;
+  }
+
   Status UnaryCall(ServerContext* context, const SimpleRequest* request,
                    SimpleResponse* response) {
     MaybeEchoMetadata(context);
diff --git a/test/distrib/cpp/run_distrib_test.sh b/test/distrib/cpp/run_distrib_test.sh
index bc84b84..15fbf28 100755
--- a/test/distrib/cpp/run_distrib_test.sh
+++ b/test/distrib/cpp/run_distrib_test.sh
@@ -30,7 +30,12 @@
 
 set -ex
 
-git clone --recursive $EXTERNAL_GIT_ROOT
+git clone $EXTERNAL_GIT_ROOT
+# clone gRPC submodules, use data from locally cloned submodules where possible
+(cd ${EXTERNAL_GIT_ROOT} && git submodule foreach 'cd /var/local/git/grpc \
+&& git submodule update --init --reference ${EXTERNAL_GIT_ROOT}/${name} \
+${name}')
+
 cd grpc
 
 cd third_party/protobuf && ./autogen.sh && \
diff --git a/tools/dockerfile/grpc_check_generated_pb_files/check_pb_files.sh b/tools/dockerfile/grpc_check_generated_pb_files/check_pb_files.sh
index 62e4175..9db7aae 100755
--- a/tools/dockerfile/grpc_check_generated_pb_files/check_pb_files.sh
+++ b/tools/dockerfile/grpc_check_generated_pb_files/check_pb_files.sh
@@ -31,7 +31,11 @@
 set -e
 
 mkdir -p /var/local/git
-git clone --recursive /var/local/jenkins/grpc /var/local/git/grpc
+git clone /var/local/jenkins/grpc /var/local/git/grpc
+# clone gRPC submodules, use data from locally cloned submodules where possible
+(cd /var/local/jenkins/grpc/ && git submodule foreach 'cd /var/local/git/grpc \
+&& git submodule update --init --reference /var/local/jenkins/grpc/${name} \
+${name}')
 
 cd /var/local/git/grpc
 
diff --git a/tools/dockerfile/interoptest/grpc_interop_csharp/build_interop.sh b/tools/dockerfile/interoptest/grpc_interop_csharp/build_interop.sh
index fd5436c..e370709 100755
--- a/tools/dockerfile/interoptest/grpc_interop_csharp/build_interop.sh
+++ b/tools/dockerfile/interoptest/grpc_interop_csharp/build_interop.sh
@@ -32,7 +32,11 @@
 set -e
 
 mkdir -p /var/local/git
-git clone --recursive /var/local/jenkins/grpc /var/local/git/grpc
+git clone /var/local/jenkins/grpc /var/local/git/grpc
+# clone gRPC submodules, use data from locally cloned submodules where possible
+(cd /var/local/jenkins/grpc/ && git submodule foreach 'cd /var/local/git/grpc \
+&& git submodule update --init --reference /var/local/jenkins/grpc/${name} \
+${name}')
 
 # copy service account keys if available
 cp -r /var/local/jenkins/service_account $HOME || true
diff --git a/tools/dockerfile/interoptest/grpc_interop_csharpcoreclr/build_interop.sh b/tools/dockerfile/interoptest/grpc_interop_csharpcoreclr/build_interop.sh
index 77cd65c..d90c899 100755
--- a/tools/dockerfile/interoptest/grpc_interop_csharpcoreclr/build_interop.sh
+++ b/tools/dockerfile/interoptest/grpc_interop_csharpcoreclr/build_interop.sh
@@ -32,7 +32,11 @@
 set -e
 
 mkdir -p /var/local/git
-git clone --recursive /var/local/jenkins/grpc /var/local/git/grpc
+git clone /var/local/jenkins/grpc /var/local/git/grpc
+# clone gRPC submodules, use data from locally cloned submodules where possible
+(cd /var/local/jenkins/grpc/ && git submodule foreach 'cd /var/local/git/grpc \
+&& git submodule update --init --reference /var/local/jenkins/grpc/${name} \
+${name}')
 
 # copy service account keys if available
 cp -r /var/local/jenkins/service_account $HOME || true
diff --git a/tools/dockerfile/interoptest/grpc_interop_cxx/build_interop.sh b/tools/dockerfile/interoptest/grpc_interop_cxx/build_interop.sh
index 1c0828d..7a7ca0d 100755
--- a/tools/dockerfile/interoptest/grpc_interop_cxx/build_interop.sh
+++ b/tools/dockerfile/interoptest/grpc_interop_cxx/build_interop.sh
@@ -32,7 +32,11 @@
 set -e
 
 mkdir -p /var/local/git
-git clone --recursive /var/local/jenkins/grpc /var/local/git/grpc
+git clone /var/local/jenkins/grpc /var/local/git/grpc
+# clone gRPC submodules, use data from locally cloned submodules where possible
+(cd /var/local/jenkins/grpc/ && git submodule foreach 'cd /var/local/git/grpc \
+&& git submodule update --init --reference /var/local/jenkins/grpc/${name} \
+${name}')
 
 # copy service account keys if available
 cp -r /var/local/jenkins/service_account $HOME || true
diff --git a/tools/dockerfile/interoptest/grpc_interop_http2/build_interop.sh b/tools/dockerfile/interoptest/grpc_interop_http2/build_interop.sh
index 46ddaf9..a1d668d 100755
--- a/tools/dockerfile/interoptest/grpc_interop_http2/build_interop.sh
+++ b/tools/dockerfile/interoptest/grpc_interop_http2/build_interop.sh
@@ -32,7 +32,11 @@
 set -e
 
 mkdir -p /var/local/git
-git clone --recursive /var/local/jenkins/grpc /var/local/git/grpc
+git clone /var/local/jenkins/grpc /var/local/git/grpc
+# clone gRPC submodules, use data from locally cloned submodules where possible
+(cd /var/local/jenkins/grpc/ && git submodule foreach 'cd /var/local/git/grpc \
+&& git submodule update --init --reference /var/local/jenkins/grpc/${name} \
+${name}')
 
 # copy service account keys if available
 cp -r /var/local/jenkins/service_account $HOME || true
diff --git a/tools/dockerfile/interoptest/grpc_interop_node/build_interop.sh b/tools/dockerfile/interoptest/grpc_interop_node/build_interop.sh
index 976f55d..4116f84 100755
--- a/tools/dockerfile/interoptest/grpc_interop_node/build_interop.sh
+++ b/tools/dockerfile/interoptest/grpc_interop_node/build_interop.sh
@@ -32,7 +32,11 @@
 set -e
 
 mkdir -p /var/local/git
-git clone --recursive /var/local/jenkins/grpc /var/local/git/grpc
+git clone /var/local/jenkins/grpc /var/local/git/grpc
+# clone gRPC submodules, use data from locally cloned submodules where possible
+(cd /var/local/jenkins/grpc/ && git submodule foreach 'cd /var/local/git/grpc \
+&& git submodule update --init --reference /var/local/jenkins/grpc/${name} \
+${name}')
 
 # copy service account keys if available
 cp -r /var/local/jenkins/service_account $HOME || true
diff --git a/tools/dockerfile/interoptest/grpc_interop_php/build_interop.sh b/tools/dockerfile/interoptest/grpc_interop_php/build_interop.sh
index 624d587..d64ec79 100755
--- a/tools/dockerfile/interoptest/grpc_interop_php/build_interop.sh
+++ b/tools/dockerfile/interoptest/grpc_interop_php/build_interop.sh
@@ -32,7 +32,11 @@
 set -ex
 
 mkdir -p /var/local/git
-git clone --recursive /var/local/jenkins/grpc /var/local/git/grpc
+git clone /var/local/jenkins/grpc /var/local/git/grpc
+# clone gRPC submodules, use data from locally cloned submodules where possible
+(cd /var/local/jenkins/grpc/ && git submodule foreach 'cd /var/local/git/grpc \
+&& git submodule update --init --reference /var/local/jenkins/grpc/${name} \
+${name}')
 
 # copy service account keys if available
 cp -r /var/local/jenkins/service_account $HOME || true
diff --git a/tools/dockerfile/interoptest/grpc_interop_php7/build_interop.sh b/tools/dockerfile/interoptest/grpc_interop_php7/build_interop.sh
index 87cb0fe..fccca4d 100755
--- a/tools/dockerfile/interoptest/grpc_interop_php7/build_interop.sh
+++ b/tools/dockerfile/interoptest/grpc_interop_php7/build_interop.sh
@@ -32,7 +32,11 @@
 set -ex
 
 mkdir -p /var/local/git
-git clone --recursive /var/local/jenkins/grpc /var/local/git/grpc
+git clone /var/local/jenkins/grpc /var/local/git/grpc
+# clone gRPC submodules, use data from locally cloned submodules where possible
+(cd /var/local/jenkins/grpc/ && git submodule foreach 'cd /var/local/git/grpc \
+&& git submodule update --init --reference /var/local/jenkins/grpc/${name} \
+${name}')
 
 # copy service account keys if available
 cp -r /var/local/jenkins/service_account $HOME || true
diff --git a/tools/dockerfile/interoptest/grpc_interop_python/build_interop.sh b/tools/dockerfile/interoptest/grpc_interop_python/build_interop.sh
index f29c59d..a6f8c7b 100755
--- a/tools/dockerfile/interoptest/grpc_interop_python/build_interop.sh
+++ b/tools/dockerfile/interoptest/grpc_interop_python/build_interop.sh
@@ -32,7 +32,11 @@
 set -e
 
 mkdir -p /var/local/git
-git clone --recursive /var/local/jenkins/grpc /var/local/git/grpc
+git clone /var/local/jenkins/grpc /var/local/git/grpc
+# clone gRPC submodules, use data from locally cloned submodules where possible
+(cd /var/local/jenkins/grpc/ && git submodule foreach 'cd /var/local/git/grpc \
+&& git submodule update --init --reference /var/local/jenkins/grpc/${name} \
+${name}')
 
 # copy service account keys if available
 cp -r /var/local/jenkins/service_account $HOME || true
diff --git a/tools/dockerfile/interoptest/grpc_interop_ruby/build_interop.sh b/tools/dockerfile/interoptest/grpc_interop_ruby/build_interop.sh
index 97b3860..6cd2fa2 100755
--- a/tools/dockerfile/interoptest/grpc_interop_ruby/build_interop.sh
+++ b/tools/dockerfile/interoptest/grpc_interop_ruby/build_interop.sh
@@ -32,7 +32,11 @@
 set -e
 
 mkdir -p /var/local/git
-git clone --recursive /var/local/jenkins/grpc /var/local/git/grpc
+git clone /var/local/jenkins/grpc /var/local/git/grpc
+# clone gRPC submodules, use data from locally cloned submodules where possible
+(cd /var/local/jenkins/grpc/ && git submodule foreach 'cd /var/local/git/grpc \
+&& git submodule update --init --reference /var/local/jenkins/grpc/${name} \
+${name}')
 
 # copy service account keys if available
 cp -r /var/local/jenkins/service_account $HOME || true
diff --git a/tools/dockerfile/stress_test/grpc_interop_stress_csharp/build_interop_stress.sh b/tools/dockerfile/stress_test/grpc_interop_stress_csharp/build_interop_stress.sh
index 1f4bf89..3451968 100755
--- a/tools/dockerfile/stress_test/grpc_interop_stress_csharp/build_interop_stress.sh
+++ b/tools/dockerfile/stress_test/grpc_interop_stress_csharp/build_interop_stress.sh
@@ -32,7 +32,11 @@
 set -e
 
 mkdir -p /var/local/git
-git clone --recursive /var/local/jenkins/grpc /var/local/git/grpc
+git clone /var/local/jenkins/grpc /var/local/git/grpc
+# clone gRPC submodules, use data from locally cloned submodules where possible
+(cd /var/local/jenkins/grpc/ && git submodule foreach 'cd /var/local/git/grpc \
+&& git submodule update --init --reference /var/local/jenkins/grpc/${name} \
+${name}')
 
 # Copy service account keys if available
 cp -r /var/local/jenkins/service_account $HOME || true
diff --git a/tools/dockerfile/stress_test/grpc_interop_stress_cxx/build_interop_stress.sh b/tools/dockerfile/stress_test/grpc_interop_stress_cxx/build_interop_stress.sh
index b67b1a1..92d1f80 100755
--- a/tools/dockerfile/stress_test/grpc_interop_stress_cxx/build_interop_stress.sh
+++ b/tools/dockerfile/stress_test/grpc_interop_stress_cxx/build_interop_stress.sh
@@ -32,7 +32,11 @@
 set -e
 
 mkdir -p /var/local/git
-git clone --recursive /var/local/jenkins/grpc /var/local/git/grpc
+git clone /var/local/jenkins/grpc /var/local/git/grpc
+# clone gRPC submodules, use data from locally cloned submodules where possible
+(cd /var/local/jenkins/grpc/ && git submodule foreach 'cd /var/local/git/grpc \
+&& git submodule update --init --reference /var/local/jenkins/grpc/${name} \
+${name}')
 
 # copy service account keys if available
 cp -r /var/local/jenkins/service_account $HOME || true
diff --git a/tools/dockerfile/stress_test/grpc_interop_stress_go/build_interop_stress.sh b/tools/dockerfile/stress_test/grpc_interop_stress_go/build_interop_stress.sh
index 919d885..9e4769c 100755
--- a/tools/dockerfile/stress_test/grpc_interop_stress_go/build_interop_stress.sh
+++ b/tools/dockerfile/stress_test/grpc_interop_stress_go/build_interop_stress.sh
@@ -38,7 +38,11 @@
 
 # Clone the 'grpc' repo. We just need this for the wrapper scripts under
 # grpc/tools/gcp/stress_tests
-git clone --recursive /var/local/jenkins/grpc /var/local/git/grpc
+git clone /var/local/jenkins/grpc /var/local/git/grpc
+# clone gRPC submodules, use data from locally cloned submodules where possible
+(cd /var/local/jenkins/grpc/ && git submodule foreach 'cd /var/local/git/grpc \
+&& git submodule update --init --reference /var/local/jenkins/grpc/${name} \
+${name}')
 
 # copy service account keys if available
 cp -r /var/local/jenkins/service_account $HOME || true
diff --git a/tools/dockerfile/stress_test/grpc_interop_stress_java/build_interop_stress.sh b/tools/dockerfile/stress_test/grpc_interop_stress_java/build_interop_stress.sh
index d4fdfbb..0194860 100755
--- a/tools/dockerfile/stress_test/grpc_interop_stress_java/build_interop_stress.sh
+++ b/tools/dockerfile/stress_test/grpc_interop_stress_java/build_interop_stress.sh
@@ -36,7 +36,11 @@
 git clone --recursive --depth 1 /var/local/jenkins/grpc-java /var/local/git/grpc-java
 
 # grpc repo (for metrics client and for the stress test wrapper scripts)
-git clone --recursive /var/local/jenkins/grpc /var/local/git/grpc
+git clone /var/local/jenkins/grpc /var/local/git/grpc
+# clone gRPC submodules, use data from locally cloned submodules where possible
+(cd /var/local/jenkins/grpc/ && git submodule foreach 'cd /var/local/git/grpc \
+&& git submodule update --init --reference /var/local/jenkins/grpc/${name} \
+${name}')
 
 # Copy service account keys if available
 cp -r /var/local/jenkins/service_account $HOME || true
diff --git a/tools/dockerfile/stress_test/grpc_interop_stress_node/build_interop_stress.sh b/tools/dockerfile/stress_test/grpc_interop_stress_node/build_interop_stress.sh
index 976f55d..4116f84 100755
--- a/tools/dockerfile/stress_test/grpc_interop_stress_node/build_interop_stress.sh
+++ b/tools/dockerfile/stress_test/grpc_interop_stress_node/build_interop_stress.sh
@@ -32,7 +32,11 @@
 set -e
 
 mkdir -p /var/local/git
-git clone --recursive /var/local/jenkins/grpc /var/local/git/grpc
+git clone /var/local/jenkins/grpc /var/local/git/grpc
+# clone gRPC submodules, use data from locally cloned submodules where possible
+(cd /var/local/jenkins/grpc/ && git submodule foreach 'cd /var/local/git/grpc \
+&& git submodule update --init --reference /var/local/jenkins/grpc/${name} \
+${name}')
 
 # copy service account keys if available
 cp -r /var/local/jenkins/service_account $HOME || true
diff --git a/tools/dockerfile/stress_test/grpc_interop_stress_php/build_interop_stress.sh b/tools/dockerfile/stress_test/grpc_interop_stress_php/build_interop_stress.sh
index a671d15..e3cca08 100755
--- a/tools/dockerfile/stress_test/grpc_interop_stress_php/build_interop_stress.sh
+++ b/tools/dockerfile/stress_test/grpc_interop_stress_php/build_interop_stress.sh
@@ -32,7 +32,11 @@
 set -ex
 
 mkdir -p /var/local/git
-git clone --recursive /var/local/jenkins/grpc /var/local/git/grpc
+git clone /var/local/jenkins/grpc /var/local/git/grpc
+# clone gRPC submodules, use data from locally cloned submodules where possible
+(cd /var/local/jenkins/grpc/ && git submodule foreach 'cd /var/local/git/grpc \
+&& git submodule update --init --reference /var/local/jenkins/grpc/${name} \
+${name}')
 
 # copy service account keys if available
 cp -r /var/local/jenkins/service_account $HOME || true
diff --git a/tools/dockerfile/stress_test/grpc_interop_stress_python/build_interop_stress.sh b/tools/dockerfile/stress_test/grpc_interop_stress_python/build_interop_stress.sh
index e65332f..1c7dc2b 100755
--- a/tools/dockerfile/stress_test/grpc_interop_stress_python/build_interop_stress.sh
+++ b/tools/dockerfile/stress_test/grpc_interop_stress_python/build_interop_stress.sh
@@ -32,13 +32,16 @@
 set -e
 
 mkdir -p /var/local/git
-git clone --recursive /var/local/jenkins/grpc /var/local/git/grpc
+git clone /var/local/jenkins/grpc /var/local/git/grpc
+# clone gRPC submodules, use data from locally cloned submodules where possible
+(cd /var/local/jenkins/grpc/ && git submodule foreach 'cd /var/local/git/grpc \
+&& git submodule update --init --reference /var/local/jenkins/grpc/${name} \
+${name}')
 
 # copy service account keys if available
 cp -r /var/local/jenkins/service_account $HOME || true
 
 cd /var/local/git/grpc
-
 tools/run_tests/run_tests.py -l python -c opt --build_only
 
 # Build c++ interop client
diff --git a/tools/dockerfile/stress_test/grpc_interop_stress_ruby/build_interop_stress.sh b/tools/dockerfile/stress_test/grpc_interop_stress_ruby/build_interop_stress.sh
index 1b7567d..019f0a4 100755
--- a/tools/dockerfile/stress_test/grpc_interop_stress_ruby/build_interop_stress.sh
+++ b/tools/dockerfile/stress_test/grpc_interop_stress_ruby/build_interop_stress.sh
@@ -32,7 +32,11 @@
 set -e
 
 mkdir -p /var/local/git
-git clone --recursive /var/local/jenkins/grpc /var/local/git/grpc
+git clone /var/local/jenkins/grpc /var/local/git/grpc
+# clone gRPC submodules, use data from locally cloned submodules where possible
+(cd /var/local/jenkins/grpc/ && git submodule foreach 'cd /var/local/git/grpc \
+&& git submodule update --init --reference /var/local/jenkins/grpc/${name} \
+${name}')
 
 # Copy service account keys if available
 cp -r /var/local/jenkins/service_account $HOME || true
diff --git a/tools/dockerfile/test/cxx_wheezy_x64/Dockerfile b/tools/dockerfile/test/cxx_wheezy_x64/Dockerfile
index c250333..f22fcac 100644
--- a/tools/dockerfile/test/cxx_wheezy_x64/Dockerfile
+++ b/tools/dockerfile/test/cxx_wheezy_x64/Dockerfile
@@ -89,6 +89,11 @@
   g++-4.4 \
   g++-4.4-multilib
 
+# set up backport to allow installation of Git version > 1.7
+RUN echo "deb http://http.debian.net/debian wheezy-backports main"   >/etc/apt/sources.list.d/wheezy-backports.list
+RUN apt-get update -qq
+RUN apt-get -t wheezy-backports install -qq git
+
 RUN wget https://openssl.org/source/old/1.0.2/openssl-1.0.2f.tar.gz
 
 ENV POST_GIT_STEP tools/dockerfile/test/cxx_wheezy_x64/post-git-setup.sh
diff --git a/tools/gce/linux_performance_worker_init.sh b/tools/gce/linux_performance_worker_init.sh
index ea80d74..4876725 100755
--- a/tools/gce/linux_performance_worker_init.sh
+++ b/tools/gce/linux_performance_worker_init.sh
@@ -128,4 +128,15 @@
 # Java dependencies - nothing as we already have Java JDK 8
 
 # Go dependencies
-sudo apt-get install -y golang-go
+# Currently, the golang package available via apt-get doesn't have the latest go.
+# Significant performance improvements with grpc-go have been observed after
+# upgrading from go 1.5 to a later version, so a later go version is preferred.
+# Following go install instructions from https://golang.org/doc/install
+GO_VERSION=1.7.1
+OS=linux
+ARCH=amd64
+curl -O https://storage.googleapis.com/golang/go${GO_VERSION}.${OS}-${ARCH}.tar.gz
+sudo tar -C /usr/local -xzf go$GO_VERSION.$OS-$ARCH.tar.gz
+# Put go on the PATH, keep the usual installation dir
+sudo ln -s /usr/local/go/bin/go /usr/bin/go
+rm go$GO_VERSION.$OS-$ARCH.tar.gz
diff --git a/tools/run_tests/dockerize/docker_run.sh b/tools/run_tests/dockerize/docker_run.sh
index f04b1cf..ee8d288 100755
--- a/tools/run_tests/dockerize/docker_run.sh
+++ b/tools/run_tests/dockerize/docker_run.sh
@@ -36,7 +36,11 @@
 if [ "$RELATIVE_COPY_PATH" == "" ]
 then
   mkdir -p /var/local/git
-  git clone --recursive "$EXTERNAL_GIT_ROOT" /var/local/git/grpc
+  git clone $EXTERNAL_GIT_ROOT /var/local/git/grpc
+  # clone gRPC submodules, use data from locally cloned submodules where possible
+  (cd ${EXTERNAL_GIT_ROOT} && git submodule foreach 'cd /var/local/git/grpc \
+  && git submodule update --init --reference ${EXTERNAL_GIT_ROOT}/${name} \
+  ${name}')
 else
   mkdir -p "/var/local/git/grpc/$RELATIVE_COPY_PATH"
   cp -r "$EXTERNAL_GIT_ROOT/$RELATIVE_COPY_PATH"/* "/var/local/git/grpc/$RELATIVE_COPY_PATH"
diff --git a/tools/run_tests/dockerize/docker_run_tests.sh b/tools/run_tests/dockerize/docker_run_tests.sh
index ef02d26..eb220ae 100755
--- a/tools/run_tests/dockerize/docker_run_tests.sh
+++ b/tools/run_tests/dockerize/docker_run_tests.sh
@@ -42,7 +42,11 @@
 chown $(whoami) $XDG_CACHE_HOME
 
 mkdir -p /var/local/git
-git clone --recursive /var/local/jenkins/grpc /var/local/git/grpc
+git clone  /var/local/jenkins/grpc /var/local/git/grpc
+# clone gRPC submodules, use data from locally cloned submodules where possible
+(cd /var/local/jenkins/grpc/ && git submodule foreach 'cd /var/local/git/grpc \
+&& git submodule update --init --reference /var/local/jenkins/grpc/${name} \
+${name}')
 
 mkdir -p reports
 
diff --git a/tools/run_tests/report_utils.py b/tools/run_tests/report_utils.py
index 5648a69..efe5dc9 100644
--- a/tools/run_tests/report_utils.py
+++ b/tools/run_tests/report_utils.py
@@ -57,11 +57,12 @@
     return msg
 
 
-def render_junit_xml_report(resultset, xml_report):
+def render_junit_xml_report(resultset, xml_report, suite_package='grpc',
+                            suite_name='tests'):
   """Generate JUnit-like XML report."""
   root = ET.Element('testsuites')
-  testsuite = ET.SubElement(root, 'testsuite', id='1', package='grpc', 
-                            name='tests')
+  testsuite = ET.SubElement(root, 'testsuite', id='1', package=suite_package,
+                            name=suite_name)
   for shortname, results in resultset.items():
     for result in results:
       xml_test = ET.SubElement(testsuite, 'testcase', name=shortname) 
diff --git a/tools/run_tests/run_tests.py b/tools/run_tests/run_tests.py
index a6f3d40..dd070b1 100755
--- a/tools/run_tests/run_tests.py
+++ b/tools/run_tests/run_tests.py
@@ -1015,6 +1015,8 @@
 argp.add_argument('-a', '--antagonists', default=0, type=int)
 argp.add_argument('-x', '--xml_report', default=None, type=str,
         help='Generates a JUnit-compatible XML report')
+argp.add_argument('--report_suite_name', default='tests', type=str,
+        help='Test suite name to use in generated JUnit XML report')
 argp.add_argument('--force_default_poller', default=False, action='store_const', const=True,
                   help='Dont try to iterate over many polling strategies when they exist')
 args = argp.parse_args()
@@ -1327,7 +1329,8 @@
 
   if build_only:
     if xml_report:
-      report_utils.render_junit_xml_report(resultset, xml_report)
+      report_utils.render_junit_xml_report(resultset, xml_report,
+                                           suite_name=args.report_suite_name)
     return []
 
   # start antagonists
@@ -1379,7 +1382,8 @@
     for antagonist in antagonists:
       antagonist.kill()
     if xml_report and resultset:
-      report_utils.render_junit_xml_report(resultset, xml_report)
+      report_utils.render_junit_xml_report(resultset, xml_report,
+                                           suite_name=args.report_suite_name)
 
   number_failures, _ = jobset.run(
       post_tests_steps, maxjobs=1, stop_on_failure=True,
diff --git a/tools/run_tests/run_tests_matrix.py b/tools/run_tests/run_tests_matrix.py
index a94f9cf..60c21a1 100755
--- a/tools/run_tests/run_tests_matrix.py
+++ b/tools/run_tests/run_tests_matrix.py
@@ -55,7 +55,8 @@
                    '--use_docker',
                    '-t',
                    '-j', str(_INNER_JOBS),
-                   '-x', 'report_%s.xml' % name] + runtests_args,
+                   '-x', 'report_%s.xml' % name,
+                   '--report_suite_name', '%s' % name] + runtests_args,
           shortname='run_tests_%s' % name,
           timeout_seconds=_RUNTESTS_TIMEOUT)
   return test_job
@@ -70,7 +71,8 @@
           cmdline=['tools/run_tests/run_tests_in_workspace.sh',
                    '-t',
                    '-j', str(_INNER_JOBS),
-                   '-x', '../report_%s.xml' % name] + runtests_args,
+                   '-x', '../report_%s.xml' % name,
+                   '--report_suite_name', '%s' % name] + runtests_args,
           environ=env,
           shortname='run_tests_%s' % name,
           timeout_seconds=_RUNTESTS_TIMEOUT)
@@ -271,7 +273,8 @@
                                      newline_on_success=True,
                                      travis=True,
                                      maxjobs=args.jobs)
-report_utils.render_junit_xml_report(resultset, 'report.xml')
+report_utils.render_junit_xml_report(resultset, 'report.xml',
+                                     suite_name='aggregate_tests')
 
 if num_failures == 0:
   jobset.message('SUCCESS', 'All run_tests.py instance finished successfully.',