Merge branch 'codegen_proto_utils_fix' into codegen_lib
diff --git a/.gitignore b/.gitignore
index 9a1dc00..502483f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -35,6 +35,7 @@
 
 # cache for run_tests.py
 .run_tests_cache
+.preprocessed_build
 
 # emacs temp files
 *~
diff --git a/.gitmodules b/.gitmodules
index 008bc5f..c37d0ab 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -14,3 +14,6 @@
 [submodule "third_party/boringssl"]
 	path = third_party/boringssl
 	url = https://boringssl.googlesource.com/boringssl
+[submodule "third_party/nanopb"]
+	path = third_party/nanopb
+	url = https://github.com/nanopb/nanopb.git
diff --git a/.travis.yml b/.travis.yml
index d2d1c8b..004d44f 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,5 +1,5 @@
 language: objective-c
-osx_image: xcode7.1
+osx_image: xcode7.2
 env:
   global:
     - CONFIG=opt
@@ -27,6 +27,6 @@
   - InteropTestsLocalCleartext
   # TODO(jcanizales): Investigate why they time out:
   # - InteropTestsRemote
-xcode_sdk: iphonesimulator9.1
+xcode_sdk: iphonesimulator9.2
 notifications:
   email: false
diff --git a/BUILD b/BUILD
index ea1dcfa..073953c 100644
--- a/BUILD
+++ b/BUILD
@@ -47,13 +47,14 @@
     "src/core/profiling/timers.h",
     "src/core/support/block_annotate.h",
     "src/core/support/env.h",
-    "src/core/support/file.h",
+    "src/core/support/load_file.h",
     "src/core/support/murmur_hash.h",
     "src/core/support/stack_lockfree.h",
     "src/core/support/string.h",
     "src/core/support/string_win32.h",
     "src/core/support/thd_internal.h",
     "src/core/support/time_precise.h",
+    "src/core/support/tmpfile.h",
     "src/core/profiling/basic_timers.c",
     "src/core/profiling/stap_timers.c",
     "src/core/support/alloc.c",
@@ -66,11 +67,9 @@
     "src/core/support/env_linux.c",
     "src/core/support/env_posix.c",
     "src/core/support/env_win32.c",
-    "src/core/support/file.c",
-    "src/core/support/file_posix.c",
-    "src/core/support/file_win32.c",
     "src/core/support/histogram.c",
     "src/core/support/host_port.c",
+    "src/core/support/load_file.c",
     "src/core/support/log.c",
     "src/core/support/log_android.c",
     "src/core/support/log_linux.c",
@@ -96,6 +95,8 @@
     "src/core/support/time_precise.c",
     "src/core/support/time_win32.c",
     "src/core/support/tls_pthread.c",
+    "src/core/support/tmpfile_posix.c",
+    "src/core/support/tmpfile_win32.c",
     "src/core/support/wrap_memcpy.c",
   ],
   hdrs = [
@@ -154,20 +155,6 @@
 cc_library(
   name = "grpc",
   srcs = [
-    "src/core/security/auth_filters.h",
-    "src/core/security/base64.h",
-    "src/core/security/credentials.h",
-    "src/core/security/handshake.h",
-    "src/core/security/json_token.h",
-    "src/core/security/jwt_verifier.h",
-    "src/core/security/secure_endpoint.h",
-    "src/core/security/security_connector.h",
-    "src/core/security/security_context.h",
-    "src/core/tsi/fake_transport_security.h",
-    "src/core/tsi/ssl_transport_security.h",
-    "src/core/tsi/ssl_types.h",
-    "src/core/tsi/transport_security.h",
-    "src/core/tsi/transport_security_interface.h",
     "src/core/census/grpc_filter.h",
     "src/core/channel/channel_args.h",
     "src/core/channel/channel_stack.h",
@@ -182,6 +169,7 @@
     "src/core/client_config/client_config.h",
     "src/core/client_config/connector.h",
     "src/core/client_config/initial_connect_string.h",
+    "src/core/client_config/lb_policies/load_balancer_api.h",
     "src/core/client_config/lb_policies/pick_first.h",
     "src/core/client_config/lb_policies/round_robin.h",
     "src/core/client_config/lb_policy.h",
@@ -232,7 +220,6 @@
     "src/core/iomgr/time_averaged_stats.h",
     "src/core/iomgr/timer.h",
     "src/core/iomgr/timer_heap.h",
-    "src/core/iomgr/timer_internal.h",
     "src/core/iomgr/udp_server.h",
     "src/core/iomgr/wakeup_fd_pipe.h",
     "src/core/iomgr/wakeup_fd_posix.h",
@@ -243,6 +230,7 @@
     "src/core/json/json_common.h",
     "src/core/json/json_reader.h",
     "src/core/json/json_writer.h",
+    "src/core/proto/grpc/lb/v0/load_balancer.pb.h",
     "src/core/statistics/census_interface.h",
     "src/core/statistics/census_rpc_stats.h",
     "src/core/surface/api_trace.h",
@@ -282,30 +270,27 @@
     "src/core/transport/static_metadata.h",
     "src/core/transport/transport.h",
     "src/core/transport/transport_impl.h",
+    "src/core/security/auth_filters.h",
+    "src/core/security/b64.h",
+    "src/core/security/credentials.h",
+    "src/core/security/handshake.h",
+    "src/core/security/json_token.h",
+    "src/core/security/jwt_verifier.h",
+    "src/core/security/secure_endpoint.h",
+    "src/core/security/security_connector.h",
+    "src/core/security/security_context.h",
+    "src/core/tsi/fake_transport_security.h",
+    "src/core/tsi/ssl_transport_security.h",
+    "src/core/tsi/ssl_types.h",
+    "src/core/tsi/transport_security.h",
+    "src/core/tsi/transport_security_interface.h",
     "src/core/census/aggregation.h",
-    "src/core/census/log.h",
+    "src/core/census/mlog.h",
     "src/core/census/rpc_metric_id.h",
-    "src/core/httpcli/httpcli_security_connector.c",
-    "src/core/security/base64.c",
-    "src/core/security/client_auth_filter.c",
-    "src/core/security/credentials.c",
-    "src/core/security/credentials_metadata.c",
-    "src/core/security/credentials_posix.c",
-    "src/core/security/credentials_win32.c",
-    "src/core/security/google_default_credentials.c",
-    "src/core/security/handshake.c",
-    "src/core/security/json_token.c",
-    "src/core/security/jwt_verifier.c",
-    "src/core/security/secure_endpoint.c",
-    "src/core/security/security_connector.c",
-    "src/core/security/security_context.c",
-    "src/core/security/server_auth_filter.c",
-    "src/core/security/server_secure_chttp2.c",
-    "src/core/surface/init_secure.c",
-    "src/core/surface/secure_channel_create.c",
-    "src/core/tsi/fake_transport_security.c",
-    "src/core/tsi/ssl_transport_security.c",
-    "src/core/tsi/transport_security.c",
+    "third_party/nanopb/pb.h",
+    "third_party/nanopb/pb_common.h",
+    "third_party/nanopb/pb_decode.h",
+    "third_party/nanopb/pb_encode.h",
     "src/core/census/grpc_context.c",
     "src/core/census/grpc_filter.c",
     "src/core/channel/channel_args.c",
@@ -321,6 +306,7 @@
     "src/core/client_config/connector.c",
     "src/core/client_config/default_initial_connect_string.c",
     "src/core/client_config/initial_connect_string.c",
+    "src/core/client_config/lb_policies/load_balancer_api.c",
     "src/core/client_config/lb_policies/pick_first.c",
     "src/core/client_config/lb_policies/round_robin.c",
     "src/core/client_config/lb_policy.c",
@@ -335,7 +321,7 @@
     "src/core/client_config/subchannel_factory.c",
     "src/core/client_config/subchannel_index.c",
     "src/core/client_config/uri_parser.c",
-    "src/core/compression/algorithm.c",
+    "src/core/compression/compression_algorithm.c",
     "src/core/compression/message_compress.c",
     "src/core/debug/trace.c",
     "src/core/httpcli/format_request.c",
@@ -385,6 +371,7 @@
     "src/core/json/json_reader.c",
     "src/core/json/json_string.c",
     "src/core/json/json_writer.c",
+    "src/core/proto/grpc/lb/v0/load_balancer.pb.c",
     "src/core/surface/alarm.c",
     "src/core/surface/api_trace.c",
     "src/core/surface/byte_buffer.c",
@@ -434,12 +421,36 @@
     "src/core/transport/static_metadata.c",
     "src/core/transport/transport.c",
     "src/core/transport/transport_op_string.c",
+    "src/core/httpcli/httpcli_security_connector.c",
+    "src/core/security/b64.c",
+    "src/core/security/client_auth_filter.c",
+    "src/core/security/credentials.c",
+    "src/core/security/credentials_metadata.c",
+    "src/core/security/credentials_posix.c",
+    "src/core/security/credentials_win32.c",
+    "src/core/security/google_default_credentials.c",
+    "src/core/security/handshake.c",
+    "src/core/security/json_token.c",
+    "src/core/security/jwt_verifier.c",
+    "src/core/security/secure_endpoint.c",
+    "src/core/security/security_connector.c",
+    "src/core/security/security_context.c",
+    "src/core/security/server_auth_filter.c",
+    "src/core/security/server_secure_chttp2.c",
+    "src/core/surface/init_secure.c",
+    "src/core/surface/secure_channel_create.c",
+    "src/core/tsi/fake_transport_security.c",
+    "src/core/tsi/ssl_transport_security.c",
+    "src/core/tsi/transport_security.c",
     "src/core/census/context.c",
     "src/core/census/initialize.c",
-    "src/core/census/log.c",
+    "src/core/census/mlog.c",
     "src/core/census/operation.c",
     "src/core/census/placeholders.c",
     "src/core/census/tracing.c",
+    "third_party/nanopb/pb_common.c",
+    "third_party/nanopb/pb_decode.c",
+    "third_party/nanopb/pb_encode.c",
   ],
   hdrs = [
     "include/grpc/grpc_security.h",
@@ -483,6 +494,7 @@
     "src/core/client_config/client_config.h",
     "src/core/client_config/connector.h",
     "src/core/client_config/initial_connect_string.h",
+    "src/core/client_config/lb_policies/load_balancer_api.h",
     "src/core/client_config/lb_policies/pick_first.h",
     "src/core/client_config/lb_policies/round_robin.h",
     "src/core/client_config/lb_policy.h",
@@ -533,7 +545,6 @@
     "src/core/iomgr/time_averaged_stats.h",
     "src/core/iomgr/timer.h",
     "src/core/iomgr/timer_heap.h",
-    "src/core/iomgr/timer_internal.h",
     "src/core/iomgr/udp_server.h",
     "src/core/iomgr/wakeup_fd_pipe.h",
     "src/core/iomgr/wakeup_fd_posix.h",
@@ -544,6 +555,7 @@
     "src/core/json/json_common.h",
     "src/core/json/json_reader.h",
     "src/core/json/json_writer.h",
+    "src/core/proto/grpc/lb/v0/load_balancer.pb.h",
     "src/core/statistics/census_interface.h",
     "src/core/statistics/census_rpc_stats.h",
     "src/core/surface/api_trace.h",
@@ -584,8 +596,12 @@
     "src/core/transport/transport.h",
     "src/core/transport/transport_impl.h",
     "src/core/census/aggregation.h",
-    "src/core/census/log.h",
+    "src/core/census/mlog.h",
     "src/core/census/rpc_metric_id.h",
+    "third_party/nanopb/pb.h",
+    "third_party/nanopb/pb_common.h",
+    "third_party/nanopb/pb_decode.h",
+    "third_party/nanopb/pb_encode.h",
     "src/core/surface/init_unsecure.c",
     "src/core/census/grpc_context.c",
     "src/core/census/grpc_filter.c",
@@ -602,6 +618,7 @@
     "src/core/client_config/connector.c",
     "src/core/client_config/default_initial_connect_string.c",
     "src/core/client_config/initial_connect_string.c",
+    "src/core/client_config/lb_policies/load_balancer_api.c",
     "src/core/client_config/lb_policies/pick_first.c",
     "src/core/client_config/lb_policies/round_robin.c",
     "src/core/client_config/lb_policy.c",
@@ -616,7 +633,7 @@
     "src/core/client_config/subchannel_factory.c",
     "src/core/client_config/subchannel_index.c",
     "src/core/client_config/uri_parser.c",
-    "src/core/compression/algorithm.c",
+    "src/core/compression/compression_algorithm.c",
     "src/core/compression/message_compress.c",
     "src/core/debug/trace.c",
     "src/core/httpcli/format_request.c",
@@ -666,6 +683,7 @@
     "src/core/json/json_reader.c",
     "src/core/json/json_string.c",
     "src/core/json/json_writer.c",
+    "src/core/proto/grpc/lb/v0/load_balancer.pb.c",
     "src/core/surface/alarm.c",
     "src/core/surface/api_trace.c",
     "src/core/surface/byte_buffer.c",
@@ -717,10 +735,13 @@
     "src/core/transport/transport_op_string.c",
     "src/core/census/context.c",
     "src/core/census/initialize.c",
-    "src/core/census/log.c",
+    "src/core/census/mlog.c",
     "src/core/census/operation.c",
     "src/core/census/placeholders.c",
     "src/core/census/tracing.c",
+    "third_party/nanopb/pb_common.c",
+    "third_party/nanopb/pb_decode.c",
+    "third_party/nanopb/pb_encode.c",
   ],
   hdrs = [
     "include/grpc/byte_buffer.h",
@@ -788,11 +809,11 @@
     "src/cpp/client/credentials.cc",
     "src/cpp/client/generic_stub.cc",
     "src/cpp/client/insecure_credentials.cc",
-    "src/cpp/common/alarm.cc",
     "src/cpp/common/call.cc",
     "src/cpp/common/channel_arguments.cc",
     "src/cpp/common/completion_queue.cc",
     "src/cpp/common/rpc_method.cc",
+    "src/cpp/proto/proto_serializer.cc",
     "src/cpp/proto/proto_utils.cc",
     "src/cpp/server/async_generic_service.cc",
     "src/cpp/server/create_default_thread_pool.cc",
@@ -882,11 +903,11 @@
     "src/cpp/client/credentials.cc",
     "src/cpp/client/generic_stub.cc",
     "src/cpp/client/insecure_credentials.cc",
-    "src/cpp/common/alarm.cc",
     "src/cpp/common/call.cc",
     "src/cpp/common/channel_arguments.cc",
     "src/cpp/common/completion_queue.cc",
     "src/cpp/common/rpc_method.cc",
+    "src/cpp/proto/proto_serializer.cc",
     "src/cpp/proto/proto_utils.cc",
     "src/cpp/server/async_generic_service.cc",
     "src/cpp/server/create_default_thread_pool.cc",
@@ -1047,11 +1068,9 @@
     "src/core/support/env_linux.c",
     "src/core/support/env_posix.c",
     "src/core/support/env_win32.c",
-    "src/core/support/file.c",
-    "src/core/support/file_posix.c",
-    "src/core/support/file_win32.c",
     "src/core/support/histogram.c",
     "src/core/support/host_port.c",
+    "src/core/support/load_file.c",
     "src/core/support/log.c",
     "src/core/support/log_android.c",
     "src/core/support/log_linux.c",
@@ -1077,6 +1096,8 @@
     "src/core/support/time_precise.c",
     "src/core/support/time_win32.c",
     "src/core/support/tls_pthread.c",
+    "src/core/support/tmpfile_posix.c",
+    "src/core/support/tmpfile_win32.c",
     "src/core/support/wrap_memcpy.c",
   ],
   hdrs = [
@@ -1125,13 +1146,14 @@
     "src/core/profiling/timers.h",
     "src/core/support/block_annotate.h",
     "src/core/support/env.h",
-    "src/core/support/file.h",
+    "src/core/support/load_file.h",
     "src/core/support/murmur_hash.h",
     "src/core/support/stack_lockfree.h",
     "src/core/support/string.h",
     "src/core/support/string_win32.h",
     "src/core/support/thd_internal.h",
     "src/core/support/time_precise.h",
+    "src/core/support/tmpfile.h",
   ],
   includes = [
     "include",
@@ -1145,27 +1167,6 @@
 objc_library(
   name = "grpc_objc",
   srcs = [
-    "src/core/httpcli/httpcli_security_connector.c",
-    "src/core/security/base64.c",
-    "src/core/security/client_auth_filter.c",
-    "src/core/security/credentials.c",
-    "src/core/security/credentials_metadata.c",
-    "src/core/security/credentials_posix.c",
-    "src/core/security/credentials_win32.c",
-    "src/core/security/google_default_credentials.c",
-    "src/core/security/handshake.c",
-    "src/core/security/json_token.c",
-    "src/core/security/jwt_verifier.c",
-    "src/core/security/secure_endpoint.c",
-    "src/core/security/security_connector.c",
-    "src/core/security/security_context.c",
-    "src/core/security/server_auth_filter.c",
-    "src/core/security/server_secure_chttp2.c",
-    "src/core/surface/init_secure.c",
-    "src/core/surface/secure_channel_create.c",
-    "src/core/tsi/fake_transport_security.c",
-    "src/core/tsi/ssl_transport_security.c",
-    "src/core/tsi/transport_security.c",
     "src/core/census/grpc_context.c",
     "src/core/census/grpc_filter.c",
     "src/core/channel/channel_args.c",
@@ -1181,6 +1182,7 @@
     "src/core/client_config/connector.c",
     "src/core/client_config/default_initial_connect_string.c",
     "src/core/client_config/initial_connect_string.c",
+    "src/core/client_config/lb_policies/load_balancer_api.c",
     "src/core/client_config/lb_policies/pick_first.c",
     "src/core/client_config/lb_policies/round_robin.c",
     "src/core/client_config/lb_policy.c",
@@ -1195,7 +1197,7 @@
     "src/core/client_config/subchannel_factory.c",
     "src/core/client_config/subchannel_index.c",
     "src/core/client_config/uri_parser.c",
-    "src/core/compression/algorithm.c",
+    "src/core/compression/compression_algorithm.c",
     "src/core/compression/message_compress.c",
     "src/core/debug/trace.c",
     "src/core/httpcli/format_request.c",
@@ -1245,6 +1247,7 @@
     "src/core/json/json_reader.c",
     "src/core/json/json_string.c",
     "src/core/json/json_writer.c",
+    "src/core/proto/grpc/lb/v0/load_balancer.pb.c",
     "src/core/surface/alarm.c",
     "src/core/surface/api_trace.c",
     "src/core/surface/byte_buffer.c",
@@ -1294,12 +1297,36 @@
     "src/core/transport/static_metadata.c",
     "src/core/transport/transport.c",
     "src/core/transport/transport_op_string.c",
+    "src/core/httpcli/httpcli_security_connector.c",
+    "src/core/security/b64.c",
+    "src/core/security/client_auth_filter.c",
+    "src/core/security/credentials.c",
+    "src/core/security/credentials_metadata.c",
+    "src/core/security/credentials_posix.c",
+    "src/core/security/credentials_win32.c",
+    "src/core/security/google_default_credentials.c",
+    "src/core/security/handshake.c",
+    "src/core/security/json_token.c",
+    "src/core/security/jwt_verifier.c",
+    "src/core/security/secure_endpoint.c",
+    "src/core/security/security_connector.c",
+    "src/core/security/security_context.c",
+    "src/core/security/server_auth_filter.c",
+    "src/core/security/server_secure_chttp2.c",
+    "src/core/surface/init_secure.c",
+    "src/core/surface/secure_channel_create.c",
+    "src/core/tsi/fake_transport_security.c",
+    "src/core/tsi/ssl_transport_security.c",
+    "src/core/tsi/transport_security.c",
     "src/core/census/context.c",
     "src/core/census/initialize.c",
-    "src/core/census/log.c",
+    "src/core/census/mlog.c",
     "src/core/census/operation.c",
     "src/core/census/placeholders.c",
     "src/core/census/tracing.c",
+    "third_party/nanopb/pb_common.c",
+    "third_party/nanopb/pb_decode.c",
+    "third_party/nanopb/pb_encode.c",
   ],
   hdrs = [
     "include/grpc/grpc_security.h",
@@ -1309,20 +1336,6 @@
     "include/grpc/grpc.h",
     "include/grpc/status.h",
     "include/grpc/census.h",
-    "src/core/security/auth_filters.h",
-    "src/core/security/base64.h",
-    "src/core/security/credentials.h",
-    "src/core/security/handshake.h",
-    "src/core/security/json_token.h",
-    "src/core/security/jwt_verifier.h",
-    "src/core/security/secure_endpoint.h",
-    "src/core/security/security_connector.h",
-    "src/core/security/security_context.h",
-    "src/core/tsi/fake_transport_security.h",
-    "src/core/tsi/ssl_transport_security.h",
-    "src/core/tsi/ssl_types.h",
-    "src/core/tsi/transport_security.h",
-    "src/core/tsi/transport_security_interface.h",
     "src/core/census/grpc_filter.h",
     "src/core/channel/channel_args.h",
     "src/core/channel/channel_stack.h",
@@ -1337,6 +1350,7 @@
     "src/core/client_config/client_config.h",
     "src/core/client_config/connector.h",
     "src/core/client_config/initial_connect_string.h",
+    "src/core/client_config/lb_policies/load_balancer_api.h",
     "src/core/client_config/lb_policies/pick_first.h",
     "src/core/client_config/lb_policies/round_robin.h",
     "src/core/client_config/lb_policy.h",
@@ -1387,7 +1401,6 @@
     "src/core/iomgr/time_averaged_stats.h",
     "src/core/iomgr/timer.h",
     "src/core/iomgr/timer_heap.h",
-    "src/core/iomgr/timer_internal.h",
     "src/core/iomgr/udp_server.h",
     "src/core/iomgr/wakeup_fd_pipe.h",
     "src/core/iomgr/wakeup_fd_posix.h",
@@ -1398,6 +1411,7 @@
     "src/core/json/json_common.h",
     "src/core/json/json_reader.h",
     "src/core/json/json_writer.h",
+    "src/core/proto/grpc/lb/v0/load_balancer.pb.h",
     "src/core/statistics/census_interface.h",
     "src/core/statistics/census_rpc_stats.h",
     "src/core/surface/api_trace.h",
@@ -1437,9 +1451,27 @@
     "src/core/transport/static_metadata.h",
     "src/core/transport/transport.h",
     "src/core/transport/transport_impl.h",
+    "src/core/security/auth_filters.h",
+    "src/core/security/b64.h",
+    "src/core/security/credentials.h",
+    "src/core/security/handshake.h",
+    "src/core/security/json_token.h",
+    "src/core/security/jwt_verifier.h",
+    "src/core/security/secure_endpoint.h",
+    "src/core/security/security_connector.h",
+    "src/core/security/security_context.h",
+    "src/core/tsi/fake_transport_security.h",
+    "src/core/tsi/ssl_transport_security.h",
+    "src/core/tsi/ssl_types.h",
+    "src/core/tsi/transport_security.h",
+    "src/core/tsi/transport_security_interface.h",
     "src/core/census/aggregation.h",
-    "src/core/census/log.h",
+    "src/core/census/mlog.h",
     "src/core/census/rpc_metric_id.h",
+    "third_party/nanopb/pb.h",
+    "third_party/nanopb/pb_common.h",
+    "third_party/nanopb/pb_decode.h",
+    "third_party/nanopb/pb_encode.h",
   ],
   includes = [
     "include",
diff --git a/INSTALL b/INSTALL
index a0df57d..e33f897 100644
--- a/INSTALL
+++ b/INSTALL
@@ -141,15 +141,7 @@
   $ make gtest.a gtest_main.a
   $ sudo cp libgtest.a libgtest_main.a /opt/local/lib
   $ sudo mkdir /opt/local/include/gtest
-  $ sudo cp -pr ../gtest-svn/include/gtest /opt/local/include/gtest 
-
-We will also need to make openssl and install it appropriately
-
-  $ cd <git directory>
-  $ cd third_party/openssl
-  $ ./config
-  $ sudo make install
-  $ cd ../../
+  $ sudo cp -pr ../gtest-svn/include/gtest /opt/local/include/gtest
 
 If you are going to make changes and need to regenerate the projects file,
 you will need to install certain modules for python.
diff --git a/Makefile b/Makefile
index 8c8be1f..4f43625 100644
--- a/Makefile
+++ b/Makefile
@@ -121,7 +121,7 @@
 LDXX_asan-noleaks = clang++
 CPPFLAGS_asan-noleaks = -O0 -fsanitize=address -fno-omit-frame-pointer -Wno-unused-command-line-argument -DGPR_NO_DIRECT_SYSCALLS
 LDFLAGS_asan-noleaks = -fsanitize=address
-DEFINES_asan-noleaks += GRPC_TEST_SLOWDOWN_BUILD_FACTOR=1.5
+DEFINES_asan-noleaks += GRPC_TEST_SLOWDOWN_BUILD_FACTOR=3
 
 VALID_CONFIG_ubsan = 1
 REQUIRE_CUSTOM_LIBRARIES_ubsan = 1
@@ -177,7 +177,7 @@
 LDXX_asan = clang++
 CPPFLAGS_asan = -O0 -fsanitize=address -fno-omit-frame-pointer -Wno-unused-command-line-argument -DGPR_NO_DIRECT_SYSCALLS
 LDFLAGS_asan = -fsanitize=address
-DEFINES_asan += GRPC_TEST_SLOWDOWN_BUILD_FACTOR=1.5
+DEFINES_asan += GRPC_TEST_SLOWDOWN_BUILD_FACTOR=3
 
 VALID_CONFIG_tsan = 1
 REQUIRE_CUSTOM_LIBRARIES_tsan = 1
@@ -187,7 +187,7 @@
 LDXX_tsan = clang++
 CPPFLAGS_tsan = -O0 -fsanitize=thread -fno-omit-frame-pointer -Wno-unused-command-line-argument -fPIE -pie -DGPR_NO_DIRECT_SYSCALLS
 LDFLAGS_tsan = -fsanitize=thread -fPIE -pie $(if $(JENKINS_BUILD),-Wl$(comma)-Ttext-segment=0x7e0000000000,)
-DEFINES_tsan += GRPC_TEST_SLOWDOWN_BUILD_FACTOR=2
+DEFINES_tsan += GRPC_TEST_SLOWDOWN_BUILD_FACTOR=5
 
 VALID_CONFIG_msan = 1
 REQUIRE_CUSTOM_LIBRARIES_msan = 1
@@ -198,7 +198,7 @@
 CPPFLAGS_msan = -O0 -fsanitize=memory -fsanitize-memory-track-origins -fno-omit-frame-pointer -DGTEST_HAS_TR1_TUPLE=0 -DGTEST_USE_OWN_TR1_TUPLE=1 -Wno-unused-command-line-argument -fPIE -pie -DGPR_NO_DIRECT_SYSCALLS
 LDFLAGS_msan = -fsanitize=memory -DGTEST_HAS_TR1_TUPLE=0 -DGTEST_USE_OWN_TR1_TUPLE=1 -fPIE -pie $(if $(JENKINS_BUILD),-Wl$(comma)-Ttext-segment=0x7e0000000000,)
 DEFINES_msan = NDEBUG
-DEFINES_msan += GRPC_TEST_SLOWDOWN_BUILD_FACTOR=2
+DEFINES_msan += GRPC_TEST_SLOWDOWN_BUILD_FACTOR=4
 
 VALID_CONFIG_mutrace = 1
 CC_mutrace = $(DEFAULT_CC)
@@ -247,7 +247,7 @@
 else
 ifeq ($(SYSTEM),Darwin)
 ifeq ($(origin AR), default)
-AR = libtool -o
+AR = libtool -no_warning_for_no_symbols -o
 endif
 STRIP ?= strip -x
 else
@@ -275,6 +275,12 @@
 CXX11_CHECK_CMD = $(CXX) -std=c++11 -o $(TMPOUT) -c test/build/c++11.cc
 HAS_CXX11 = $(shell $(CXX11_CHECK_CMD) 2> /dev/null && echo true || echo false)
 
+CHECK_SHADOW_WORKS_CMD = $(CC) -std=c99 -Werror -Wshadow -o $(TMPOUT) -c test/build/shadow.c
+HAS_WORKING_SHADOW = $(shell $(CHECK_SHADOW_WORKS_CMD) 2> /dev/null && echo true || echo false)
+ifeq ($(HAS_WORKING_SHADOW),true)
+W_SHADOW=-Wshadow
+endif
+
 CHECK_NO_SHIFT_NEGATIVE_VALUE_CMD = $(CC) -std=c99 -Werror -Wno-shift-negative-value -o $(TMPOUT) -c test/build/empty.c
 HAS_NO_SHIFT_NEGATIVE_VALUE = $(shell $(CHECK_NO_SHIFT_NEGATIVE_VALUE_CMD) 2> /dev/null && echo true || echo false)
 ifeq ($(HAS_NO_SHIFT_NEGATIVE_VALUE),true)
@@ -295,7 +301,7 @@
 DEFINES += $(EXTRA_DEFINES)
 endif
 
-CFLAGS += -std=c99 -Wsign-conversion -Wconversion -Wshadow
+CFLAGS += -std=c99 -Wsign-conversion -Wconversion $(W_SHADOW)
 ifeq ($(HAS_CXX11),true)
 CXXFLAGS += -std=c++11
 else
@@ -426,6 +432,7 @@
 
 OPENSSL_ALPN_CHECK_CMD = $(CC) $(CPPFLAGS) $(CFLAGS) -o $(TMPOUT) test/build/openssl-alpn.c $(addprefix -l, $(OPENSSL_LIBS)) $(LDFLAGS)
 OPENSSL_NPN_CHECK_CMD = $(CC) $(CPPFLAGS) $(CFLAGS) -o $(TMPOUT) test/build/openssl-npn.c $(addprefix -l, $(OPENSSL_LIBS)) $(LDFLAGS)
+BORINGSSL_COMPILE_CHECK_CMD = $(CC) $(CPPFLAGS) -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX $(CFLAGS) -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-unknown-pragmas -Wno-implicit-function-declaration -Wno-unused-variable -Wno-sign-compare -o $(TMPOUT) test/build/boringssl.c $(LDFLAGS)
 ZLIB_CHECK_CMD = $(CC) $(CPPFLAGS) $(CFLAGS) -o $(TMPOUT) test/build/zlib.c -lz $(LDFLAGS)
 PROTOBUF_CHECK_CMD = $(CXX) $(CPPFLAGS) $(CXXFLAGS) -o $(TMPOUT) test/build/protobuf.cc -lprotobuf $(LDFLAGS)
 
@@ -510,10 +517,13 @@
 # Note that for testing purposes, one can do:
 #   make HAS_EMBEDDED_OPENSSL_ALPN=false
 # to emulate the fact we do not have OpenSSL in the third_party folder.
-ifeq ($(wildcard third_party/boringssl/include/openssl/ssl.h),)
+ifneq ($(wildcard third_party/openssl-1.0.2f/libssl.a),)
+HAS_EMBEDDED_OPENSSL_ALPN = third_party/openssl-1.0.2f
+else ifeq ($(wildcard third_party/boringssl/include/openssl/ssl.h),)
 HAS_EMBEDDED_OPENSSL_ALPN = false
 else
-HAS_EMBEDDED_OPENSSL_ALPN = true
+CAN_COMPILE_EMBEDDED_OPENSSL ?= $(shell $(BORINGSSL_COMPILE_CHECK_CMD) 2> /dev/null && echo true || echo false)
+HAS_EMBEDDED_OPENSSL_ALPN = $(CAN_COMPILE_EMBEDDED_OPENSSL)
 endif
 
 ifeq ($(wildcard third_party/zlib/zlib.h),)
@@ -572,8 +582,8 @@
 EMBED_OPENSSL ?= false
 NO_SECURE ?= false
 else # HAS_SYSTEM_OPENSSL_ALPN=false
-ifeq ($(HAS_EMBEDDED_OPENSSL_ALPN),true)
-EMBED_OPENSSL ?= true
+ifneq ($(HAS_EMBEDDED_OPENSSL_ALPN),false)
+EMBED_OPENSSL ?= $(HAS_EMBEDDED_OPENSSL_ALPN)
 NO_SECURE ?= false
 else # HAS_EMBEDDED_OPENSSL_ALPN=false
 ifeq ($(HAS_SYSTEM_OPENSSL_NPN),true)
@@ -594,6 +604,12 @@
 OPENSSL_MERGE_OBJS += $(LIBBORINGSSL_OBJS)
 # need to prefix these to ensure overriding system libraries
 CPPFLAGS := -Ithird_party/boringssl/include $(CPPFLAGS)
+else ifneq ($(EMBED_OPENSSL),false)
+OPENSSL_DEP += $(EMBED_OPENSSL)/libssl.a $(EMBED_OPENSSL)/libcrypto.a
+OPENSSL_MERGE_LIBS += $(EMBED_OPENSSL)/libssl.a $(EMBED_OPENSSL)/libcrypto.a
+OPENSSL_MERGE_OBJS += $(wildcard $(EMBED_OPENSSL)/grpc_obj/*.o)
+# need to prefix these to ensure overriding system libraries
+CPPFLAGS := -I$(EMBED_OPENSSL)/include $(CPPFLAGS)
 else # EMBED_OPENSSL=false
 ifeq ($(HAS_PKG_CONFIG),true)
 OPENSSL_PKG_CONFIG = true
@@ -768,8 +784,9 @@
 	@echo
 	@echo "DEPENDENCY ERROR"
 	@echo
-	@echo "The target you are trying to run requires OpenSSL."
-	@echo "Your system doesn't have it, and neither does the third_party directory."
+	@echo "The target you are trying to run requires an OpenSSL implementation."
+	@echo "Your system doesn't have one, and either the third_party directory"
+	@echo "doesn't have it, or your compiler can't build BoringSSL."
 	@echo
 	@echo "Please consult INSTALL to get more information."
 	@echo
@@ -826,7 +843,6 @@
 alpn_test: $(BINDIR)/$(CONFIG)/alpn_test
 bin_encoder_test: $(BINDIR)/$(CONFIG)/bin_encoder_test
 census_context_test: $(BINDIR)/$(CONFIG)/census_context_test
-census_log_test: $(BINDIR)/$(CONFIG)/census_log_test
 channel_create_test: $(BINDIR)/$(CONFIG)/channel_create_test
 chttp2_hpack_encoder_test: $(BINDIR)/$(CONFIG)/chttp2_hpack_encoder_test
 chttp2_status_conversion_test: $(BINDIR)/$(CONFIG)/chttp2_status_conversion_test
@@ -848,9 +864,9 @@
 gpr_cmdline_test: $(BINDIR)/$(CONFIG)/gpr_cmdline_test
 gpr_cpu_test: $(BINDIR)/$(CONFIG)/gpr_cpu_test
 gpr_env_test: $(BINDIR)/$(CONFIG)/gpr_env_test
-gpr_file_test: $(BINDIR)/$(CONFIG)/gpr_file_test
 gpr_histogram_test: $(BINDIR)/$(CONFIG)/gpr_histogram_test
 gpr_host_port_test: $(BINDIR)/$(CONFIG)/gpr_host_port_test
+gpr_load_file_test: $(BINDIR)/$(CONFIG)/gpr_load_file_test
 gpr_log_test: $(BINDIR)/$(CONFIG)/gpr_log_test
 gpr_slice_buffer_test: $(BINDIR)/$(CONFIG)/gpr_slice_buffer_test
 gpr_slice_test: $(BINDIR)/$(CONFIG)/gpr_slice_test
@@ -862,7 +878,7 @@
 gpr_tls_test: $(BINDIR)/$(CONFIG)/gpr_tls_test
 gpr_useful_test: $(BINDIR)/$(CONFIG)/gpr_useful_test
 grpc_auth_context_test: $(BINDIR)/$(CONFIG)/grpc_auth_context_test
-grpc_base64_test: $(BINDIR)/$(CONFIG)/grpc_base64_test
+grpc_b64_test: $(BINDIR)/$(CONFIG)/grpc_b64_test
 grpc_byte_buffer_reader_test: $(BINDIR)/$(CONFIG)/grpc_byte_buffer_reader_test
 grpc_channel_args_test: $(BINDIR)/$(CONFIG)/grpc_channel_args_test
 grpc_channel_stack_test: $(BINDIR)/$(CONFIG)/grpc_channel_stack_test
@@ -892,6 +908,7 @@
 lb_policies_test: $(BINDIR)/$(CONFIG)/lb_policies_test
 low_level_ping_pong_benchmark: $(BINDIR)/$(CONFIG)/low_level_ping_pong_benchmark
 message_compress_test: $(BINDIR)/$(CONFIG)/message_compress_test
+mlog_test: $(BINDIR)/$(CONFIG)/mlog_test
 multiple_server_queues_test: $(BINDIR)/$(CONFIG)/multiple_server_queues_test
 murmur_hash_test: $(BINDIR)/$(CONFIG)/murmur_hash_test
 no_server_test: $(BINDIR)/$(CONFIG)/no_server_test
@@ -941,6 +958,7 @@
 grpc_objective_c_plugin: $(BINDIR)/$(CONFIG)/grpc_objective_c_plugin
 grpc_python_plugin: $(BINDIR)/$(CONFIG)/grpc_python_plugin
 grpc_ruby_plugin: $(BINDIR)/$(CONFIG)/grpc_ruby_plugin
+grpclb_api_test: $(BINDIR)/$(CONFIG)/grpclb_api_test
 hybrid_end2end_test: $(BINDIR)/$(CONFIG)/hybrid_end2end_test
 interop_client: $(BINDIR)/$(CONFIG)/interop_client
 interop_server: $(BINDIR)/$(CONFIG)/interop_server
@@ -1135,7 +1153,6 @@
   $(BINDIR)/$(CONFIG)/alpn_test \
   $(BINDIR)/$(CONFIG)/bin_encoder_test \
   $(BINDIR)/$(CONFIG)/census_context_test \
-  $(BINDIR)/$(CONFIG)/census_log_test \
   $(BINDIR)/$(CONFIG)/channel_create_test \
   $(BINDIR)/$(CONFIG)/chttp2_hpack_encoder_test \
   $(BINDIR)/$(CONFIG)/chttp2_status_conversion_test \
@@ -1155,9 +1172,9 @@
   $(BINDIR)/$(CONFIG)/gpr_cmdline_test \
   $(BINDIR)/$(CONFIG)/gpr_cpu_test \
   $(BINDIR)/$(CONFIG)/gpr_env_test \
-  $(BINDIR)/$(CONFIG)/gpr_file_test \
   $(BINDIR)/$(CONFIG)/gpr_histogram_test \
   $(BINDIR)/$(CONFIG)/gpr_host_port_test \
+  $(BINDIR)/$(CONFIG)/gpr_load_file_test \
   $(BINDIR)/$(CONFIG)/gpr_log_test \
   $(BINDIR)/$(CONFIG)/gpr_slice_buffer_test \
   $(BINDIR)/$(CONFIG)/gpr_slice_test \
@@ -1169,7 +1186,7 @@
   $(BINDIR)/$(CONFIG)/gpr_tls_test \
   $(BINDIR)/$(CONFIG)/gpr_useful_test \
   $(BINDIR)/$(CONFIG)/grpc_auth_context_test \
-  $(BINDIR)/$(CONFIG)/grpc_base64_test \
+  $(BINDIR)/$(CONFIG)/grpc_b64_test \
   $(BINDIR)/$(CONFIG)/grpc_byte_buffer_reader_test \
   $(BINDIR)/$(CONFIG)/grpc_channel_args_test \
   $(BINDIR)/$(CONFIG)/grpc_channel_stack_test \
@@ -1194,6 +1211,7 @@
   $(BINDIR)/$(CONFIG)/lame_client_test \
   $(BINDIR)/$(CONFIG)/lb_policies_test \
   $(BINDIR)/$(CONFIG)/message_compress_test \
+  $(BINDIR)/$(CONFIG)/mlog_test \
   $(BINDIR)/$(CONFIG)/multiple_server_queues_test \
   $(BINDIR)/$(CONFIG)/murmur_hash_test \
   $(BINDIR)/$(CONFIG)/no_server_test \
@@ -1285,6 +1303,7 @@
   $(BINDIR)/$(CONFIG)/generic_async_streaming_ping_pong_test \
   $(BINDIR)/$(CONFIG)/generic_end2end_test \
   $(BINDIR)/$(CONFIG)/grpc_cli \
+  $(BINDIR)/$(CONFIG)/grpclb_api_test \
   $(BINDIR)/$(CONFIG)/hybrid_end2end_test \
   $(BINDIR)/$(CONFIG)/interop_client \
   $(BINDIR)/$(CONFIG)/interop_server \
@@ -1371,8 +1390,6 @@
 	$(Q) $(BINDIR)/$(CONFIG)/bin_encoder_test || ( echo test bin_encoder_test failed ; exit 1 )
 	$(E) "[RUN]     Testing census_context_test"
 	$(Q) $(BINDIR)/$(CONFIG)/census_context_test || ( echo test census_context_test failed ; exit 1 )
-	$(E) "[RUN]     Testing census_log_test"
-	$(Q) $(BINDIR)/$(CONFIG)/census_log_test || ( echo test census_log_test failed ; exit 1 )
 	$(E) "[RUN]     Testing channel_create_test"
 	$(Q) $(BINDIR)/$(CONFIG)/channel_create_test || ( echo test channel_create_test failed ; exit 1 )
 	$(E) "[RUN]     Testing chttp2_hpack_encoder_test"
@@ -1407,12 +1424,12 @@
 	$(Q) $(BINDIR)/$(CONFIG)/gpr_cpu_test || ( echo test gpr_cpu_test failed ; exit 1 )
 	$(E) "[RUN]     Testing gpr_env_test"
 	$(Q) $(BINDIR)/$(CONFIG)/gpr_env_test || ( echo test gpr_env_test failed ; exit 1 )
-	$(E) "[RUN]     Testing gpr_file_test"
-	$(Q) $(BINDIR)/$(CONFIG)/gpr_file_test || ( echo test gpr_file_test failed ; exit 1 )
 	$(E) "[RUN]     Testing gpr_histogram_test"
 	$(Q) $(BINDIR)/$(CONFIG)/gpr_histogram_test || ( echo test gpr_histogram_test failed ; exit 1 )
 	$(E) "[RUN]     Testing gpr_host_port_test"
 	$(Q) $(BINDIR)/$(CONFIG)/gpr_host_port_test || ( echo test gpr_host_port_test failed ; exit 1 )
+	$(E) "[RUN]     Testing gpr_load_file_test"
+	$(Q) $(BINDIR)/$(CONFIG)/gpr_load_file_test || ( echo test gpr_load_file_test failed ; exit 1 )
 	$(E) "[RUN]     Testing gpr_log_test"
 	$(Q) $(BINDIR)/$(CONFIG)/gpr_log_test || ( echo test gpr_log_test failed ; exit 1 )
 	$(E) "[RUN]     Testing gpr_slice_buffer_test"
@@ -1435,8 +1452,8 @@
 	$(Q) $(BINDIR)/$(CONFIG)/gpr_useful_test || ( echo test gpr_useful_test failed ; exit 1 )
 	$(E) "[RUN]     Testing grpc_auth_context_test"
 	$(Q) $(BINDIR)/$(CONFIG)/grpc_auth_context_test || ( echo test grpc_auth_context_test failed ; exit 1 )
-	$(E) "[RUN]     Testing grpc_base64_test"
-	$(Q) $(BINDIR)/$(CONFIG)/grpc_base64_test || ( echo test grpc_base64_test failed ; exit 1 )
+	$(E) "[RUN]     Testing grpc_b64_test"
+	$(Q) $(BINDIR)/$(CONFIG)/grpc_b64_test || ( echo test grpc_b64_test failed ; exit 1 )
 	$(E) "[RUN]     Testing grpc_byte_buffer_reader_test"
 	$(Q) $(BINDIR)/$(CONFIG)/grpc_byte_buffer_reader_test || ( echo test grpc_byte_buffer_reader_test failed ; exit 1 )
 	$(E) "[RUN]     Testing grpc_channel_args_test"
@@ -1483,6 +1500,8 @@
 	$(Q) $(BINDIR)/$(CONFIG)/lb_policies_test || ( echo test lb_policies_test failed ; exit 1 )
 	$(E) "[RUN]     Testing message_compress_test"
 	$(Q) $(BINDIR)/$(CONFIG)/message_compress_test || ( echo test message_compress_test failed ; exit 1 )
+	$(E) "[RUN]     Testing mlog_test"
+	$(Q) $(BINDIR)/$(CONFIG)/mlog_test || ( echo test mlog_test failed ; exit 1 )
 	$(E) "[RUN]     Testing multiple_server_queues_test"
 	$(Q) $(BINDIR)/$(CONFIG)/multiple_server_queues_test || ( echo test multiple_server_queues_test failed ; exit 1 )
 	$(E) "[RUN]     Testing murmur_hash_test"
@@ -1595,6 +1614,8 @@
 	$(Q) $(BINDIR)/$(CONFIG)/generic_async_streaming_ping_pong_test || ( echo test generic_async_streaming_ping_pong_test failed ; exit 1 )
 	$(E) "[RUN]     Testing generic_end2end_test"
 	$(Q) $(BINDIR)/$(CONFIG)/generic_end2end_test || ( echo test generic_end2end_test failed ; exit 1 )
+	$(E) "[RUN]     Testing grpclb_api_test"
+	$(Q) $(BINDIR)/$(CONFIG)/grpclb_api_test || ( echo test grpclb_api_test failed ; exit 1 )
 	$(E) "[RUN]     Testing hybrid_end2end_test"
 	$(Q) $(BINDIR)/$(CONFIG)/hybrid_end2end_test || ( echo test hybrid_end2end_test failed ; exit 1 )
 	$(E) "[RUN]     Testing interop_test"
@@ -1747,6 +1768,21 @@
 	$(Q) echo "$(GRPCXX_UNSECURE_PC_FILE)" | tr , '\n' >$@
 
 ifeq ($(NO_PROTOC),true)
+$(GENDIR)/src/proto/grpc/lb/v0/load_balancer.pb.cc: protoc_dep_error
+$(GENDIR)/src/proto/grpc/lb/v0/load_balancer.grpc.pb.cc: protoc_dep_error
+else
+$(GENDIR)/src/proto/grpc/lb/v0/load_balancer.pb.cc: src/proto/grpc/lb/v0/load_balancer.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) 
+	$(E) "[PROTOC]  Generating protobuf CC file from $<"
+	$(Q) mkdir -p `dirname $@`
+	$(Q) $(PROTOC) --cpp_out=$(GENDIR) $<
+
+$(GENDIR)/src/proto/grpc/lb/v0/load_balancer.grpc.pb.cc: src/proto/grpc/lb/v0/load_balancer.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) 
+	$(E) "[GRPC]    Generating gRPC's protobuf service CC file from $<"
+	$(Q) mkdir -p `dirname $@`
+	$(Q) $(PROTOC) --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(BINDIR)/$(CONFIG)/grpc_cpp_plugin $<
+endif
+
+ifeq ($(NO_PROTOC),true)
 $(GENDIR)/src/proto/grpc/testing/control.pb.cc: protoc_dep_error
 $(GENDIR)/src/proto/grpc/testing/control.grpc.pb.cc: protoc_dep_error
 else
@@ -2180,11 +2216,9 @@
     src/core/support/env_linux.c \
     src/core/support/env_posix.c \
     src/core/support/env_win32.c \
-    src/core/support/file.c \
-    src/core/support/file_posix.c \
-    src/core/support/file_win32.c \
     src/core/support/histogram.c \
     src/core/support/host_port.c \
+    src/core/support/load_file.c \
     src/core/support/log.c \
     src/core/support/log_android.c \
     src/core/support/log_linux.c \
@@ -2210,6 +2244,8 @@
     src/core/support/time_precise.c \
     src/core/support/time_win32.c \
     src/core/support/tls_pthread.c \
+    src/core/support/tmpfile_posix.c \
+    src/core/support/tmpfile_win32.c \
     src/core/support/wrap_memcpy.c \
 
 PUBLIC_HEADERS_C += \
@@ -2265,7 +2301,7 @@
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libgpr.a
 	$(Q) $(AR) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBGPR_OBJS) 
 ifeq ($(SYSTEM),Darwin)
-	$(Q) ranlib $(LIBDIR)/$(CONFIG)/libgpr.a
+	$(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libgpr.a
 endif
 
 
@@ -2306,7 +2342,7 @@
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libgpr_test_util.a
 	$(Q) $(AR) $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBGPR_TEST_UTIL_OBJS) 
 ifeq ($(SYSTEM),Darwin)
-	$(Q) ranlib $(LIBDIR)/$(CONFIG)/libgpr_test_util.a
+	$(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libgpr_test_util.a
 endif
 
 
@@ -2318,27 +2354,6 @@
 
 
 LIBGRPC_SRC = \
-    src/core/httpcli/httpcli_security_connector.c \
-    src/core/security/base64.c \
-    src/core/security/client_auth_filter.c \
-    src/core/security/credentials.c \
-    src/core/security/credentials_metadata.c \
-    src/core/security/credentials_posix.c \
-    src/core/security/credentials_win32.c \
-    src/core/security/google_default_credentials.c \
-    src/core/security/handshake.c \
-    src/core/security/json_token.c \
-    src/core/security/jwt_verifier.c \
-    src/core/security/secure_endpoint.c \
-    src/core/security/security_connector.c \
-    src/core/security/security_context.c \
-    src/core/security/server_auth_filter.c \
-    src/core/security/server_secure_chttp2.c \
-    src/core/surface/init_secure.c \
-    src/core/surface/secure_channel_create.c \
-    src/core/tsi/fake_transport_security.c \
-    src/core/tsi/ssl_transport_security.c \
-    src/core/tsi/transport_security.c \
     src/core/census/grpc_context.c \
     src/core/census/grpc_filter.c \
     src/core/channel/channel_args.c \
@@ -2354,6 +2369,7 @@
     src/core/client_config/connector.c \
     src/core/client_config/default_initial_connect_string.c \
     src/core/client_config/initial_connect_string.c \
+    src/core/client_config/lb_policies/load_balancer_api.c \
     src/core/client_config/lb_policies/pick_first.c \
     src/core/client_config/lb_policies/round_robin.c \
     src/core/client_config/lb_policy.c \
@@ -2368,7 +2384,7 @@
     src/core/client_config/subchannel_factory.c \
     src/core/client_config/subchannel_index.c \
     src/core/client_config/uri_parser.c \
-    src/core/compression/algorithm.c \
+    src/core/compression/compression_algorithm.c \
     src/core/compression/message_compress.c \
     src/core/debug/trace.c \
     src/core/httpcli/format_request.c \
@@ -2418,6 +2434,7 @@
     src/core/json/json_reader.c \
     src/core/json/json_string.c \
     src/core/json/json_writer.c \
+    src/core/proto/grpc/lb/v0/load_balancer.pb.c \
     src/core/surface/alarm.c \
     src/core/surface/api_trace.c \
     src/core/surface/byte_buffer.c \
@@ -2467,12 +2484,36 @@
     src/core/transport/static_metadata.c \
     src/core/transport/transport.c \
     src/core/transport/transport_op_string.c \
+    src/core/httpcli/httpcli_security_connector.c \
+    src/core/security/b64.c \
+    src/core/security/client_auth_filter.c \
+    src/core/security/credentials.c \
+    src/core/security/credentials_metadata.c \
+    src/core/security/credentials_posix.c \
+    src/core/security/credentials_win32.c \
+    src/core/security/google_default_credentials.c \
+    src/core/security/handshake.c \
+    src/core/security/json_token.c \
+    src/core/security/jwt_verifier.c \
+    src/core/security/secure_endpoint.c \
+    src/core/security/security_connector.c \
+    src/core/security/security_context.c \
+    src/core/security/server_auth_filter.c \
+    src/core/security/server_secure_chttp2.c \
+    src/core/surface/init_secure.c \
+    src/core/surface/secure_channel_create.c \
+    src/core/tsi/fake_transport_security.c \
+    src/core/tsi/ssl_transport_security.c \
+    src/core/tsi/transport_security.c \
     src/core/census/context.c \
     src/core/census/initialize.c \
-    src/core/census/log.c \
+    src/core/census/mlog.c \
     src/core/census/operation.c \
     src/core/census/placeholders.c \
     src/core/census/tracing.c \
+    third_party/nanopb/pb_common.c \
+    third_party/nanopb/pb_decode.c \
+    third_party/nanopb/pb_encode.c \
 
 PUBLIC_HEADERS_C += \
     include/grpc/grpc_security.h \
@@ -2503,7 +2544,7 @@
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libgrpc.a
 	$(Q) $(AR) $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBGRPC_OBJS)  $(LIBGPR_OBJS)  $(ZLIB_MERGE_OBJS)  $(OPENSSL_MERGE_OBJS) 
 ifeq ($(SYSTEM),Darwin)
-	$(Q) ranlib $(LIBDIR)/$(CONFIG)/libgrpc.a
+	$(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libgrpc.a
 endif
 
 
@@ -2568,7 +2609,7 @@
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libgrpc_codegen_lib.a
 	$(Q) $(AR) $(LIBDIR)/$(CONFIG)/libgrpc_codegen_lib.a $(LIBGRPC_CODEGEN_LIB_OBJS) 
 ifeq ($(SYSTEM),Darwin)
-	$(Q) ranlib $(LIBDIR)/$(CONFIG)/libgrpc_codegen_lib.a
+	$(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libgrpc_codegen_lib.a
 endif
 
 
@@ -2614,7 +2655,7 @@
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a
 	$(Q) $(AR) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBGRPC_TEST_UTIL_OBJS) 
 ifeq ($(SYSTEM),Darwin)
-	$(Q) ranlib $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a
+	$(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a
 endif
 
 
@@ -2650,7 +2691,7 @@
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a
 	$(Q) $(AR) $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBGRPC_TEST_UTIL_UNSECURE_OBJS) 
 ifeq ($(SYSTEM),Darwin)
-	$(Q) ranlib $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a
+	$(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a
 endif
 
 
@@ -2678,6 +2719,7 @@
     src/core/client_config/connector.c \
     src/core/client_config/default_initial_connect_string.c \
     src/core/client_config/initial_connect_string.c \
+    src/core/client_config/lb_policies/load_balancer_api.c \
     src/core/client_config/lb_policies/pick_first.c \
     src/core/client_config/lb_policies/round_robin.c \
     src/core/client_config/lb_policy.c \
@@ -2692,7 +2734,7 @@
     src/core/client_config/subchannel_factory.c \
     src/core/client_config/subchannel_index.c \
     src/core/client_config/uri_parser.c \
-    src/core/compression/algorithm.c \
+    src/core/compression/compression_algorithm.c \
     src/core/compression/message_compress.c \
     src/core/debug/trace.c \
     src/core/httpcli/format_request.c \
@@ -2742,6 +2784,7 @@
     src/core/json/json_reader.c \
     src/core/json/json_string.c \
     src/core/json/json_writer.c \
+    src/core/proto/grpc/lb/v0/load_balancer.pb.c \
     src/core/surface/alarm.c \
     src/core/surface/api_trace.c \
     src/core/surface/byte_buffer.c \
@@ -2793,10 +2836,13 @@
     src/core/transport/transport_op_string.c \
     src/core/census/context.c \
     src/core/census/initialize.c \
-    src/core/census/log.c \
+    src/core/census/mlog.c \
     src/core/census/operation.c \
     src/core/census/placeholders.c \
     src/core/census/tracing.c \
+    third_party/nanopb/pb_common.c \
+    third_party/nanopb/pb_decode.c \
+    third_party/nanopb/pb_encode.c \
 
 PUBLIC_HEADERS_C += \
     include/grpc/byte_buffer.h \
@@ -2815,7 +2861,7 @@
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a
 	$(Q) $(AR) $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBGRPC_UNSECURE_OBJS)  $(LIBGPR_OBJS)  $(ZLIB_MERGE_OBJS) 
 ifeq ($(SYSTEM),Darwin)
-	$(Q) ranlib $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a
+	$(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a
 endif
 
 
@@ -2858,7 +2904,7 @@
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libgrpc_zookeeper.a
 	$(Q) $(AR) $(LIBDIR)/$(CONFIG)/libgrpc_zookeeper.a $(LIBGRPC_ZOOKEEPER_OBJS) 
 ifeq ($(SYSTEM),Darwin)
-	$(Q) ranlib $(LIBDIR)/$(CONFIG)/libgrpc_zookeeper.a
+	$(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libgrpc_zookeeper.a
 endif
 
 
@@ -2909,7 +2955,7 @@
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libreconnect_server.a
 	$(Q) $(AR) $(LIBDIR)/$(CONFIG)/libreconnect_server.a $(LIBRECONNECT_SERVER_OBJS) 
 ifeq ($(SYSTEM),Darwin)
-	$(Q) ranlib $(LIBDIR)/$(CONFIG)/libreconnect_server.a
+	$(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libreconnect_server.a
 endif
 
 
@@ -2947,7 +2993,7 @@
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libtest_tcp_server.a
 	$(Q) $(AR) $(LIBDIR)/$(CONFIG)/libtest_tcp_server.a $(LIBTEST_TCP_SERVER_OBJS) 
 ifeq ($(SYSTEM),Darwin)
-	$(Q) ranlib $(LIBDIR)/$(CONFIG)/libtest_tcp_server.a
+	$(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libtest_tcp_server.a
 endif
 
 
@@ -2977,11 +3023,11 @@
     src/cpp/client/credentials.cc \
     src/cpp/client/generic_stub.cc \
     src/cpp/client/insecure_credentials.cc \
-    src/cpp/common/alarm.cc \
     src/cpp/common/call.cc \
     src/cpp/common/channel_arguments.cc \
     src/cpp/common/completion_queue.cc \
     src/cpp/common/rpc_method.cc \
+    src/cpp/proto/proto_serializer.cc \
     src/cpp/proto/proto_utils.cc \
     src/cpp/server/async_generic_service.cc \
     src/cpp/server/create_default_thread_pool.cc \
@@ -3072,7 +3118,7 @@
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libgrpc++.a
 	$(Q) $(AR) $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBGRPC++_OBJS)  $(LIBGPR_OBJS)  $(ZLIB_MERGE_OBJS) 
 ifeq ($(SYSTEM),Darwin)
-	$(Q) ranlib $(LIBDIR)/$(CONFIG)/libgrpc++.a
+	$(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libgrpc++.a
 endif
 
 
@@ -3172,7 +3218,7 @@
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libgrpc++_codegen_lib.a
 	$(Q) $(AR) $(LIBDIR)/$(CONFIG)/libgrpc++_codegen_lib.a $(LIBGRPC++_CODEGEN_LIB_OBJS) 
 ifeq ($(SYSTEM),Darwin)
-	$(Q) ranlib $(LIBDIR)/$(CONFIG)/libgrpc++_codegen_lib.a
+	$(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libgrpc++_codegen_lib.a
 endif
 
 
@@ -3216,7 +3262,7 @@
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a
 	$(Q) $(AR) $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LIBGRPC++_TEST_CONFIG_OBJS) 
 ifeq ($(SYSTEM),Darwin)
-	$(Q) ranlib $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a
+	$(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a
 endif
 
 
@@ -3243,6 +3289,7 @@
     test/cpp/util/create_test_channel.cc \
     test/cpp/util/string_ref_helper.cc \
     test/cpp/util/subprocess.cc \
+    test/cpp/util/test_credentials_provider.cc \
 
 
 LIBGRPC++_TEST_UTIL_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBGRPC++_TEST_UTIL_SRC))))
@@ -3272,7 +3319,7 @@
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a
 	$(Q) $(AR) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBGRPC++_TEST_UTIL_OBJS) 
 ifeq ($(SYSTEM),Darwin)
-	$(Q) ranlib $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a
+	$(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a
 endif
 
 
@@ -3293,6 +3340,7 @@
 $(OBJDIR)/$(CONFIG)/test/cpp/util/create_test_channel.o: $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc
 $(OBJDIR)/$(CONFIG)/test/cpp/util/string_ref_helper.o: $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc
 $(OBJDIR)/$(CONFIG)/test/cpp/util/subprocess.o: $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc
+$(OBJDIR)/$(CONFIG)/test/cpp/util/test_credentials_provider.o: $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc
 
 
 LIBGRPC++_UNSECURE_SRC = \
@@ -3304,11 +3352,11 @@
     src/cpp/client/credentials.cc \
     src/cpp/client/generic_stub.cc \
     src/cpp/client/insecure_credentials.cc \
-    src/cpp/common/alarm.cc \
     src/cpp/common/call.cc \
     src/cpp/common/channel_arguments.cc \
     src/cpp/common/completion_queue.cc \
     src/cpp/common/rpc_method.cc \
+    src/cpp/proto/proto_serializer.cc \
     src/cpp/proto/proto_utils.cc \
     src/cpp/server/async_generic_service.cc \
     src/cpp/server/create_default_thread_pool.cc \
@@ -3389,7 +3437,7 @@
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a
 	$(Q) $(AR) $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBGRPC++_UNSECURE_OBJS)  $(LIBGPR_OBJS)  $(ZLIB_MERGE_OBJS) 
 ifeq ($(SYSTEM),Darwin)
-	$(Q) ranlib $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a
+	$(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a
 endif
 
 
@@ -3460,7 +3508,7 @@
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libgrpc_plugin_support.a
 	$(Q) $(AR) $(LIBDIR)/$(CONFIG)/libgrpc_plugin_support.a $(LIBGRPC_PLUGIN_SUPPORT_OBJS) 
 ifeq ($(SYSTEM),Darwin)
-	$(Q) ranlib $(LIBDIR)/$(CONFIG)/libgrpc_plugin_support.a
+	$(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libgrpc_plugin_support.a
 endif
 
 
@@ -3505,7 +3553,7 @@
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libinterop_client_helper.a
 	$(Q) $(AR) $(LIBDIR)/$(CONFIG)/libinterop_client_helper.a $(LIBINTEROP_CLIENT_HELPER_OBJS) 
 ifeq ($(SYSTEM),Darwin)
-	$(Q) ranlib $(LIBDIR)/$(CONFIG)/libinterop_client_helper.a
+	$(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libinterop_client_helper.a
 endif
 
 
@@ -3558,7 +3606,7 @@
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libinterop_client_main.a
 	$(Q) $(AR) $(LIBDIR)/$(CONFIG)/libinterop_client_main.a $(LIBINTEROP_CLIENT_MAIN_OBJS) 
 ifeq ($(SYSTEM),Darwin)
-	$(Q) ranlib $(LIBDIR)/$(CONFIG)/libinterop_client_main.a
+	$(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libinterop_client_main.a
 endif
 
 
@@ -3608,7 +3656,7 @@
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libinterop_server_helper.a
 	$(Q) $(AR) $(LIBDIR)/$(CONFIG)/libinterop_server_helper.a $(LIBINTEROP_SERVER_HELPER_OBJS) 
 ifeq ($(SYSTEM),Darwin)
-	$(Q) ranlib $(LIBDIR)/$(CONFIG)/libinterop_server_helper.a
+	$(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libinterop_server_helper.a
 endif
 
 
@@ -3629,7 +3677,7 @@
     $(GENDIR)/src/proto/grpc/testing/empty.pb.cc $(GENDIR)/src/proto/grpc/testing/empty.grpc.pb.cc \
     $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc \
     $(GENDIR)/src/proto/grpc/testing/test.pb.cc $(GENDIR)/src/proto/grpc/testing/test.grpc.pb.cc \
-    test/cpp/interop/server.cc \
+    test/cpp/interop/server_main.cc \
 
 
 LIBINTEROP_SERVER_MAIN_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBINTEROP_SERVER_MAIN_SRC))))
@@ -3659,7 +3707,7 @@
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libinterop_server_main.a
 	$(Q) $(AR) $(LIBDIR)/$(CONFIG)/libinterop_server_main.a $(LIBINTEROP_SERVER_MAIN_OBJS) 
 ifeq ($(SYSTEM),Darwin)
-	$(Q) ranlib $(LIBDIR)/$(CONFIG)/libinterop_server_main.a
+	$(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libinterop_server_main.a
 endif
 
 
@@ -3674,7 +3722,7 @@
 -include $(LIBINTEROP_SERVER_MAIN_OBJS:.o=.dep)
 endif
 endif
-$(OBJDIR)/$(CONFIG)/test/cpp/interop/server.o: $(GENDIR)/src/proto/grpc/testing/empty.pb.cc $(GENDIR)/src/proto/grpc/testing/empty.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/test.pb.cc $(GENDIR)/src/proto/grpc/testing/test.grpc.pb.cc
+$(OBJDIR)/$(CONFIG)/test/cpp/interop/server_main.o: $(GENDIR)/src/proto/grpc/testing/empty.pb.cc $(GENDIR)/src/proto/grpc/testing/empty.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/test.pb.cc $(GENDIR)/src/proto/grpc/testing/test.grpc.pb.cc
 
 
 LIBQPS_SRC = \
@@ -3693,7 +3741,7 @@
     test/cpp/qps/report.cc \
     test/cpp/qps/server_async.cc \
     test/cpp/qps/server_sync.cc \
-    test/cpp/qps/timer.cc \
+    test/cpp/qps/usage_timer.cc \
     test/cpp/util/benchmark_config.cc \
 
 
@@ -3724,7 +3772,7 @@
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libqps.a
 	$(Q) $(AR) $(LIBDIR)/$(CONFIG)/libqps.a $(LIBQPS_OBJS) 
 ifeq ($(SYSTEM),Darwin)
-	$(Q) ranlib $(LIBDIR)/$(CONFIG)/libqps.a
+	$(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libqps.a
 endif
 
 
@@ -3748,7 +3796,7 @@
 $(OBJDIR)/$(CONFIG)/test/cpp/qps/report.o: $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/control.pb.cc $(GENDIR)/src/proto/grpc/testing/control.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/services.pb.cc $(GENDIR)/src/proto/grpc/testing/services.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/perf_db.pb.cc $(GENDIR)/src/proto/grpc/testing/perf_db.grpc.pb.cc
 $(OBJDIR)/$(CONFIG)/test/cpp/qps/server_async.o: $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/control.pb.cc $(GENDIR)/src/proto/grpc/testing/control.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/services.pb.cc $(GENDIR)/src/proto/grpc/testing/services.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/perf_db.pb.cc $(GENDIR)/src/proto/grpc/testing/perf_db.grpc.pb.cc
 $(OBJDIR)/$(CONFIG)/test/cpp/qps/server_sync.o: $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/control.pb.cc $(GENDIR)/src/proto/grpc/testing/control.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/services.pb.cc $(GENDIR)/src/proto/grpc/testing/services.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/perf_db.pb.cc $(GENDIR)/src/proto/grpc/testing/perf_db.grpc.pb.cc
-$(OBJDIR)/$(CONFIG)/test/cpp/qps/timer.o: $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/control.pb.cc $(GENDIR)/src/proto/grpc/testing/control.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/services.pb.cc $(GENDIR)/src/proto/grpc/testing/services.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/perf_db.pb.cc $(GENDIR)/src/proto/grpc/testing/perf_db.grpc.pb.cc
+$(OBJDIR)/$(CONFIG)/test/cpp/qps/usage_timer.o: $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/control.pb.cc $(GENDIR)/src/proto/grpc/testing/control.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/services.pb.cc $(GENDIR)/src/proto/grpc/testing/services.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/perf_db.pb.cc $(GENDIR)/src/proto/grpc/testing/perf_db.grpc.pb.cc
 $(OBJDIR)/$(CONFIG)/test/cpp/util/benchmark_config.o: $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/control.pb.cc $(GENDIR)/src/proto/grpc/testing/control.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/services.pb.cc $(GENDIR)/src/proto/grpc/testing/services.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/perf_db.pb.cc $(GENDIR)/src/proto/grpc/testing/perf_db.grpc.pb.cc
 
 
@@ -3776,7 +3824,7 @@
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext.a
 	$(Q) $(AR) $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext.a $(LIBGRPC_CSHARP_EXT_OBJS) 
 ifeq ($(SYSTEM),Darwin)
-	$(Q) ranlib $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext.a
+	$(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext.a
 endif
 
 
@@ -4116,7 +4164,7 @@
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl.a
 	$(Q) $(AR) $(LIBDIR)/$(CONFIG)/libboringssl.a $(LIBBORINGSSL_OBJS) 
 ifeq ($(SYSTEM),Darwin)
-	$(Q) ranlib $(LIBDIR)/$(CONFIG)/libboringssl.a
+	$(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl.a
 endif
 
 
@@ -4153,7 +4201,7 @@
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a
 	$(Q) $(AR) $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBBORINGSSL_TEST_UTIL_OBJS) 
 ifeq ($(SYSTEM),Darwin)
-	$(Q) ranlib $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a
+	$(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a
 endif
 
 
@@ -4190,7 +4238,7 @@
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_aes_test_lib.a
 	$(Q) $(AR) $(LIBDIR)/$(CONFIG)/libboringssl_aes_test_lib.a $(LIBBORINGSSL_AES_TEST_LIB_OBJS) 
 ifeq ($(SYSTEM),Darwin)
-	$(Q) ranlib $(LIBDIR)/$(CONFIG)/libboringssl_aes_test_lib.a
+	$(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_aes_test_lib.a
 endif
 
 
@@ -4227,7 +4275,7 @@
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_base64_test_lib.a
 	$(Q) $(AR) $(LIBDIR)/$(CONFIG)/libboringssl_base64_test_lib.a $(LIBBORINGSSL_BASE64_TEST_LIB_OBJS) 
 ifeq ($(SYSTEM),Darwin)
-	$(Q) ranlib $(LIBDIR)/$(CONFIG)/libboringssl_base64_test_lib.a
+	$(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_base64_test_lib.a
 endif
 
 
@@ -4264,7 +4312,7 @@
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_bio_test_lib.a
 	$(Q) $(AR) $(LIBDIR)/$(CONFIG)/libboringssl_bio_test_lib.a $(LIBBORINGSSL_BIO_TEST_LIB_OBJS) 
 ifeq ($(SYSTEM),Darwin)
-	$(Q) ranlib $(LIBDIR)/$(CONFIG)/libboringssl_bio_test_lib.a
+	$(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_bio_test_lib.a
 endif
 
 
@@ -4301,7 +4349,7 @@
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_bn_test_lib.a
 	$(Q) $(AR) $(LIBDIR)/$(CONFIG)/libboringssl_bn_test_lib.a $(LIBBORINGSSL_BN_TEST_LIB_OBJS) 
 ifeq ($(SYSTEM),Darwin)
-	$(Q) ranlib $(LIBDIR)/$(CONFIG)/libboringssl_bn_test_lib.a
+	$(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_bn_test_lib.a
 endif
 
 
@@ -4338,7 +4386,7 @@
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_bytestring_test_lib.a
 	$(Q) $(AR) $(LIBDIR)/$(CONFIG)/libboringssl_bytestring_test_lib.a $(LIBBORINGSSL_BYTESTRING_TEST_LIB_OBJS) 
 ifeq ($(SYSTEM),Darwin)
-	$(Q) ranlib $(LIBDIR)/$(CONFIG)/libboringssl_bytestring_test_lib.a
+	$(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_bytestring_test_lib.a
 endif
 
 
@@ -4375,7 +4423,7 @@
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_aead_test_lib.a
 	$(Q) $(AR) $(LIBDIR)/$(CONFIG)/libboringssl_aead_test_lib.a $(LIBBORINGSSL_AEAD_TEST_LIB_OBJS) 
 ifeq ($(SYSTEM),Darwin)
-	$(Q) ranlib $(LIBDIR)/$(CONFIG)/libboringssl_aead_test_lib.a
+	$(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_aead_test_lib.a
 endif
 
 
@@ -4412,7 +4460,7 @@
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_cipher_test_lib.a
 	$(Q) $(AR) $(LIBDIR)/$(CONFIG)/libboringssl_cipher_test_lib.a $(LIBBORINGSSL_CIPHER_TEST_LIB_OBJS) 
 ifeq ($(SYSTEM),Darwin)
-	$(Q) ranlib $(LIBDIR)/$(CONFIG)/libboringssl_cipher_test_lib.a
+	$(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_cipher_test_lib.a
 endif
 
 
@@ -4449,7 +4497,7 @@
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_cmac_test_lib.a
 	$(Q) $(AR) $(LIBDIR)/$(CONFIG)/libboringssl_cmac_test_lib.a $(LIBBORINGSSL_CMAC_TEST_LIB_OBJS) 
 ifeq ($(SYSTEM),Darwin)
-	$(Q) ranlib $(LIBDIR)/$(CONFIG)/libboringssl_cmac_test_lib.a
+	$(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_cmac_test_lib.a
 endif
 
 
@@ -4477,7 +4525,7 @@
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_constant_time_test_lib.a
 	$(Q) $(AR) $(LIBDIR)/$(CONFIG)/libboringssl_constant_time_test_lib.a $(LIBBORINGSSL_CONSTANT_TIME_TEST_LIB_OBJS) 
 ifeq ($(SYSTEM),Darwin)
-	$(Q) ranlib $(LIBDIR)/$(CONFIG)/libboringssl_constant_time_test_lib.a
+	$(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_constant_time_test_lib.a
 endif
 
 
@@ -4512,7 +4560,7 @@
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_ed25519_test_lib.a
 	$(Q) $(AR) $(LIBDIR)/$(CONFIG)/libboringssl_ed25519_test_lib.a $(LIBBORINGSSL_ED25519_TEST_LIB_OBJS) 
 ifeq ($(SYSTEM),Darwin)
-	$(Q) ranlib $(LIBDIR)/$(CONFIG)/libboringssl_ed25519_test_lib.a
+	$(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_ed25519_test_lib.a
 endif
 
 
@@ -4549,7 +4597,7 @@
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_x25519_test_lib.a
 	$(Q) $(AR) $(LIBDIR)/$(CONFIG)/libboringssl_x25519_test_lib.a $(LIBBORINGSSL_X25519_TEST_LIB_OBJS) 
 ifeq ($(SYSTEM),Darwin)
-	$(Q) ranlib $(LIBDIR)/$(CONFIG)/libboringssl_x25519_test_lib.a
+	$(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_x25519_test_lib.a
 endif
 
 
@@ -4586,7 +4634,7 @@
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_dh_test_lib.a
 	$(Q) $(AR) $(LIBDIR)/$(CONFIG)/libboringssl_dh_test_lib.a $(LIBBORINGSSL_DH_TEST_LIB_OBJS) 
 ifeq ($(SYSTEM),Darwin)
-	$(Q) ranlib $(LIBDIR)/$(CONFIG)/libboringssl_dh_test_lib.a
+	$(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_dh_test_lib.a
 endif
 
 
@@ -4623,7 +4671,7 @@
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_digest_test_lib.a
 	$(Q) $(AR) $(LIBDIR)/$(CONFIG)/libboringssl_digest_test_lib.a $(LIBBORINGSSL_DIGEST_TEST_LIB_OBJS) 
 ifeq ($(SYSTEM),Darwin)
-	$(Q) ranlib $(LIBDIR)/$(CONFIG)/libboringssl_digest_test_lib.a
+	$(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_digest_test_lib.a
 endif
 
 
@@ -4651,7 +4699,7 @@
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_dsa_test_lib.a
 	$(Q) $(AR) $(LIBDIR)/$(CONFIG)/libboringssl_dsa_test_lib.a $(LIBBORINGSSL_DSA_TEST_LIB_OBJS) 
 ifeq ($(SYSTEM),Darwin)
-	$(Q) ranlib $(LIBDIR)/$(CONFIG)/libboringssl_dsa_test_lib.a
+	$(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_dsa_test_lib.a
 endif
 
 
@@ -4686,7 +4734,7 @@
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_ec_test_lib.a
 	$(Q) $(AR) $(LIBDIR)/$(CONFIG)/libboringssl_ec_test_lib.a $(LIBBORINGSSL_EC_TEST_LIB_OBJS) 
 ifeq ($(SYSTEM),Darwin)
-	$(Q) ranlib $(LIBDIR)/$(CONFIG)/libboringssl_ec_test_lib.a
+	$(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_ec_test_lib.a
 endif
 
 
@@ -4714,7 +4762,7 @@
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_example_mul_lib.a
 	$(Q) $(AR) $(LIBDIR)/$(CONFIG)/libboringssl_example_mul_lib.a $(LIBBORINGSSL_EXAMPLE_MUL_LIB_OBJS) 
 ifeq ($(SYSTEM),Darwin)
-	$(Q) ranlib $(LIBDIR)/$(CONFIG)/libboringssl_example_mul_lib.a
+	$(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_example_mul_lib.a
 endif
 
 
@@ -4749,7 +4797,7 @@
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_ecdsa_test_lib.a
 	$(Q) $(AR) $(LIBDIR)/$(CONFIG)/libboringssl_ecdsa_test_lib.a $(LIBBORINGSSL_ECDSA_TEST_LIB_OBJS) 
 ifeq ($(SYSTEM),Darwin)
-	$(Q) ranlib $(LIBDIR)/$(CONFIG)/libboringssl_ecdsa_test_lib.a
+	$(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_ecdsa_test_lib.a
 endif
 
 
@@ -4786,7 +4834,7 @@
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_err_test_lib.a
 	$(Q) $(AR) $(LIBDIR)/$(CONFIG)/libboringssl_err_test_lib.a $(LIBBORINGSSL_ERR_TEST_LIB_OBJS) 
 ifeq ($(SYSTEM),Darwin)
-	$(Q) ranlib $(LIBDIR)/$(CONFIG)/libboringssl_err_test_lib.a
+	$(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_err_test_lib.a
 endif
 
 
@@ -4823,7 +4871,7 @@
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_evp_extra_test_lib.a
 	$(Q) $(AR) $(LIBDIR)/$(CONFIG)/libboringssl_evp_extra_test_lib.a $(LIBBORINGSSL_EVP_EXTRA_TEST_LIB_OBJS) 
 ifeq ($(SYSTEM),Darwin)
-	$(Q) ranlib $(LIBDIR)/$(CONFIG)/libboringssl_evp_extra_test_lib.a
+	$(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_evp_extra_test_lib.a
 endif
 
 
@@ -4860,7 +4908,7 @@
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_evp_test_lib.a
 	$(Q) $(AR) $(LIBDIR)/$(CONFIG)/libboringssl_evp_test_lib.a $(LIBBORINGSSL_EVP_TEST_LIB_OBJS) 
 ifeq ($(SYSTEM),Darwin)
-	$(Q) ranlib $(LIBDIR)/$(CONFIG)/libboringssl_evp_test_lib.a
+	$(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_evp_test_lib.a
 endif
 
 
@@ -4897,7 +4945,7 @@
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_pbkdf_test_lib.a
 	$(Q) $(AR) $(LIBDIR)/$(CONFIG)/libboringssl_pbkdf_test_lib.a $(LIBBORINGSSL_PBKDF_TEST_LIB_OBJS) 
 ifeq ($(SYSTEM),Darwin)
-	$(Q) ranlib $(LIBDIR)/$(CONFIG)/libboringssl_pbkdf_test_lib.a
+	$(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_pbkdf_test_lib.a
 endif
 
 
@@ -4925,7 +4973,7 @@
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_hkdf_test_lib.a
 	$(Q) $(AR) $(LIBDIR)/$(CONFIG)/libboringssl_hkdf_test_lib.a $(LIBBORINGSSL_HKDF_TEST_LIB_OBJS) 
 ifeq ($(SYSTEM),Darwin)
-	$(Q) ranlib $(LIBDIR)/$(CONFIG)/libboringssl_hkdf_test_lib.a
+	$(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_hkdf_test_lib.a
 endif
 
 
@@ -4960,7 +5008,7 @@
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_hmac_test_lib.a
 	$(Q) $(AR) $(LIBDIR)/$(CONFIG)/libboringssl_hmac_test_lib.a $(LIBBORINGSSL_HMAC_TEST_LIB_OBJS) 
 ifeq ($(SYSTEM),Darwin)
-	$(Q) ranlib $(LIBDIR)/$(CONFIG)/libboringssl_hmac_test_lib.a
+	$(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_hmac_test_lib.a
 endif
 
 
@@ -4988,7 +5036,7 @@
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_lhash_test_lib.a
 	$(Q) $(AR) $(LIBDIR)/$(CONFIG)/libboringssl_lhash_test_lib.a $(LIBBORINGSSL_LHASH_TEST_LIB_OBJS) 
 ifeq ($(SYSTEM),Darwin)
-	$(Q) ranlib $(LIBDIR)/$(CONFIG)/libboringssl_lhash_test_lib.a
+	$(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_lhash_test_lib.a
 endif
 
 
@@ -5014,7 +5062,7 @@
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_gcm_test_lib.a
 	$(Q) $(AR) $(LIBDIR)/$(CONFIG)/libboringssl_gcm_test_lib.a $(LIBBORINGSSL_GCM_TEST_LIB_OBJS) 
 ifeq ($(SYSTEM),Darwin)
-	$(Q) ranlib $(LIBDIR)/$(CONFIG)/libboringssl_gcm_test_lib.a
+	$(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_gcm_test_lib.a
 endif
 
 
@@ -5049,7 +5097,7 @@
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_pkcs12_test_lib.a
 	$(Q) $(AR) $(LIBDIR)/$(CONFIG)/libboringssl_pkcs12_test_lib.a $(LIBBORINGSSL_PKCS12_TEST_LIB_OBJS) 
 ifeq ($(SYSTEM),Darwin)
-	$(Q) ranlib $(LIBDIR)/$(CONFIG)/libboringssl_pkcs12_test_lib.a
+	$(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_pkcs12_test_lib.a
 endif
 
 
@@ -5086,7 +5134,7 @@
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_pkcs8_test_lib.a
 	$(Q) $(AR) $(LIBDIR)/$(CONFIG)/libboringssl_pkcs8_test_lib.a $(LIBBORINGSSL_PKCS8_TEST_LIB_OBJS) 
 ifeq ($(SYSTEM),Darwin)
-	$(Q) ranlib $(LIBDIR)/$(CONFIG)/libboringssl_pkcs8_test_lib.a
+	$(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_pkcs8_test_lib.a
 endif
 
 
@@ -5123,7 +5171,7 @@
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_poly1305_test_lib.a
 	$(Q) $(AR) $(LIBDIR)/$(CONFIG)/libboringssl_poly1305_test_lib.a $(LIBBORINGSSL_POLY1305_TEST_LIB_OBJS) 
 ifeq ($(SYSTEM),Darwin)
-	$(Q) ranlib $(LIBDIR)/$(CONFIG)/libboringssl_poly1305_test_lib.a
+	$(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_poly1305_test_lib.a
 endif
 
 
@@ -5151,7 +5199,7 @@
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_refcount_test_lib.a
 	$(Q) $(AR) $(LIBDIR)/$(CONFIG)/libboringssl_refcount_test_lib.a $(LIBBORINGSSL_REFCOUNT_TEST_LIB_OBJS) 
 ifeq ($(SYSTEM),Darwin)
-	$(Q) ranlib $(LIBDIR)/$(CONFIG)/libboringssl_refcount_test_lib.a
+	$(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_refcount_test_lib.a
 endif
 
 
@@ -5186,7 +5234,7 @@
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_rsa_test_lib.a
 	$(Q) $(AR) $(LIBDIR)/$(CONFIG)/libboringssl_rsa_test_lib.a $(LIBBORINGSSL_RSA_TEST_LIB_OBJS) 
 ifeq ($(SYSTEM),Darwin)
-	$(Q) ranlib $(LIBDIR)/$(CONFIG)/libboringssl_rsa_test_lib.a
+	$(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_rsa_test_lib.a
 endif
 
 
@@ -5214,7 +5262,7 @@
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_thread_test_lib.a
 	$(Q) $(AR) $(LIBDIR)/$(CONFIG)/libboringssl_thread_test_lib.a $(LIBBORINGSSL_THREAD_TEST_LIB_OBJS) 
 ifeq ($(SYSTEM),Darwin)
-	$(Q) ranlib $(LIBDIR)/$(CONFIG)/libboringssl_thread_test_lib.a
+	$(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_thread_test_lib.a
 endif
 
 
@@ -5240,7 +5288,7 @@
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_pkcs7_test_lib.a
 	$(Q) $(AR) $(LIBDIR)/$(CONFIG)/libboringssl_pkcs7_test_lib.a $(LIBBORINGSSL_PKCS7_TEST_LIB_OBJS) 
 ifeq ($(SYSTEM),Darwin)
-	$(Q) ranlib $(LIBDIR)/$(CONFIG)/libboringssl_pkcs7_test_lib.a
+	$(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_pkcs7_test_lib.a
 endif
 
 
@@ -5266,7 +5314,7 @@
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_tab_test_lib.a
 	$(Q) $(AR) $(LIBDIR)/$(CONFIG)/libboringssl_tab_test_lib.a $(LIBBORINGSSL_TAB_TEST_LIB_OBJS) 
 ifeq ($(SYSTEM),Darwin)
-	$(Q) ranlib $(LIBDIR)/$(CONFIG)/libboringssl_tab_test_lib.a
+	$(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_tab_test_lib.a
 endif
 
 
@@ -5292,7 +5340,7 @@
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_v3name_test_lib.a
 	$(Q) $(AR) $(LIBDIR)/$(CONFIG)/libboringssl_v3name_test_lib.a $(LIBBORINGSSL_V3NAME_TEST_LIB_OBJS) 
 ifeq ($(SYSTEM),Darwin)
-	$(Q) ranlib $(LIBDIR)/$(CONFIG)/libboringssl_v3name_test_lib.a
+	$(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_v3name_test_lib.a
 endif
 
 
@@ -5318,7 +5366,7 @@
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_pqueue_test_lib.a
 	$(Q) $(AR) $(LIBDIR)/$(CONFIG)/libboringssl_pqueue_test_lib.a $(LIBBORINGSSL_PQUEUE_TEST_LIB_OBJS) 
 ifeq ($(SYSTEM),Darwin)
-	$(Q) ranlib $(LIBDIR)/$(CONFIG)/libboringssl_pqueue_test_lib.a
+	$(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_pqueue_test_lib.a
 endif
 
 
@@ -5353,7 +5401,7 @@
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_ssl_test_lib.a
 	$(Q) $(AR) $(LIBDIR)/$(CONFIG)/libboringssl_ssl_test_lib.a $(LIBBORINGSSL_SSL_TEST_LIB_OBJS) 
 ifeq ($(SYSTEM),Darwin)
-	$(Q) ranlib $(LIBDIR)/$(CONFIG)/libboringssl_ssl_test_lib.a
+	$(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_ssl_test_lib.a
 endif
 
 
@@ -5394,7 +5442,7 @@
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libz.a
 	$(Q) $(AR) $(LIBDIR)/$(CONFIG)/libz.a $(LIBZ_OBJS) 
 ifeq ($(SYSTEM),Darwin)
-	$(Q) ranlib $(LIBDIR)/$(CONFIG)/libz.a
+	$(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libz.a
 endif
 
 
@@ -5428,7 +5476,7 @@
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libbad_client_test.a
 	$(Q) $(AR) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBBAD_CLIENT_TEST_OBJS) 
 ifeq ($(SYSTEM),Darwin)
-	$(Q) ranlib $(LIBDIR)/$(CONFIG)/libbad_client_test.a
+	$(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libbad_client_test.a
 endif
 
 
@@ -5444,7 +5492,7 @@
 
 
 LIBBAD_SSL_TEST_SERVER_SRC = \
-    test/core/bad_ssl/server.c \
+    test/core/bad_ssl/server_common.c \
 
 
 LIBBAD_SSL_TEST_SERVER_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBBAD_SSL_TEST_SERVER_SRC))))
@@ -5466,7 +5514,7 @@
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libbad_ssl_test_server.a
 	$(Q) $(AR) $(LIBDIR)/$(CONFIG)/libbad_ssl_test_server.a $(LIBBAD_SSL_TEST_SERVER_OBJS) 
 ifeq ($(SYSTEM),Darwin)
-	$(Q) ranlib $(LIBDIR)/$(CONFIG)/libbad_ssl_test_server.a
+	$(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libbad_ssl_test_server.a
 endif
 
 
@@ -5492,9 +5540,8 @@
     test/core/end2end/tests/cancel_before_invoke.c \
     test/core/end2end/tests/cancel_in_a_vacuum.c \
     test/core/end2end/tests/cancel_with_status.c \
-    test/core/end2end/tests/channel_connectivity.c \
-    test/core/end2end/tests/channel_ping.c \
     test/core/end2end/tests/compressed_payload.c \
+    test/core/end2end/tests/connectivity.c \
     test/core/end2end/tests/default_host.c \
     test/core/end2end/tests/disappearing_server.c \
     test/core/end2end/tests/empty_batch.c \
@@ -5505,10 +5552,10 @@
     test/core/end2end/tests/large_metadata.c \
     test/core/end2end/tests/max_concurrent_streams.c \
     test/core/end2end/tests/max_message_length.c \
-    test/core/end2end/tests/metadata.c \
     test/core/end2end/tests/negative_deadline.c \
     test/core/end2end/tests/no_op.c \
     test/core/end2end/tests/payload.c \
+    test/core/end2end/tests/ping.c \
     test/core/end2end/tests/ping_pong_streaming.c \
     test/core/end2end/tests/registered_call.c \
     test/core/end2end/tests/request_with_flags.c \
@@ -5517,6 +5564,7 @@
     test/core/end2end/tests/shutdown_finishes_calls.c \
     test/core/end2end/tests/shutdown_finishes_tags.c \
     test/core/end2end/tests/simple_delayed_request.c \
+    test/core/end2end/tests/simple_metadata.c \
     test/core/end2end/tests/simple_request.c \
     test/core/end2end/tests/trailing_metadata.c \
 
@@ -5540,7 +5588,7 @@
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libend2end_tests.a
 	$(Q) $(AR) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBEND2END_TESTS_OBJS) 
 ifeq ($(SYSTEM),Darwin)
-	$(Q) ranlib $(LIBDIR)/$(CONFIG)/libend2end_tests.a
+	$(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libend2end_tests.a
 endif
 
 
@@ -5565,9 +5613,8 @@
     test/core/end2end/tests/cancel_before_invoke.c \
     test/core/end2end/tests/cancel_in_a_vacuum.c \
     test/core/end2end/tests/cancel_with_status.c \
-    test/core/end2end/tests/channel_connectivity.c \
-    test/core/end2end/tests/channel_ping.c \
     test/core/end2end/tests/compressed_payload.c \
+    test/core/end2end/tests/connectivity.c \
     test/core/end2end/tests/default_host.c \
     test/core/end2end/tests/disappearing_server.c \
     test/core/end2end/tests/empty_batch.c \
@@ -5578,10 +5625,10 @@
     test/core/end2end/tests/large_metadata.c \
     test/core/end2end/tests/max_concurrent_streams.c \
     test/core/end2end/tests/max_message_length.c \
-    test/core/end2end/tests/metadata.c \
     test/core/end2end/tests/negative_deadline.c \
     test/core/end2end/tests/no_op.c \
     test/core/end2end/tests/payload.c \
+    test/core/end2end/tests/ping.c \
     test/core/end2end/tests/ping_pong_streaming.c \
     test/core/end2end/tests/registered_call.c \
     test/core/end2end/tests/request_with_flags.c \
@@ -5590,6 +5637,7 @@
     test/core/end2end/tests/shutdown_finishes_calls.c \
     test/core/end2end/tests/shutdown_finishes_tags.c \
     test/core/end2end/tests/simple_delayed_request.c \
+    test/core/end2end/tests/simple_metadata.c \
     test/core/end2end/tests/simple_request.c \
     test/core/end2end/tests/trailing_metadata.c \
 
@@ -5603,7 +5651,7 @@
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a
 	$(Q) $(AR) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBEND2END_NOSEC_TESTS_OBJS) 
 ifeq ($(SYSTEM),Darwin)
-	$(Q) ranlib $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a
+	$(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a
 endif
 
 
@@ -5639,7 +5687,7 @@
 	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libend2end_certs.a
 	$(Q) $(AR) $(LIBDIR)/$(CONFIG)/libend2end_certs.a $(LIBEND2END_CERTS_OBJS) 
 ifeq ($(SYSTEM),Darwin)
-	$(Q) ranlib $(LIBDIR)/$(CONFIG)/libend2end_certs.a
+	$(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libend2end_certs.a
 endif
 
 
@@ -5850,38 +5898,6 @@
 endif
 
 
-CENSUS_LOG_TEST_SRC = \
-    test/core/census/log_test.c \
-
-CENSUS_LOG_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(CENSUS_LOG_TEST_SRC))))
-ifeq ($(NO_SECURE),true)
-
-# You can't build secure targets if you don't have OpenSSL.
-
-$(BINDIR)/$(CONFIG)/census_log_test: openssl_dep_error
-
-else
-
-
-
-$(BINDIR)/$(CONFIG)/census_log_test: $(CENSUS_LOG_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
-	$(E) "[LD]      Linking $@"
-	$(Q) mkdir -p `dirname $@`
-	$(Q) $(LD) $(LDFLAGS) $(CENSUS_LOG_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/census_log_test
-
-endif
-
-$(OBJDIR)/$(CONFIG)/test/core/census/log_test.o:  $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
-
-deps_census_log_test: $(CENSUS_LOG_TEST_OBJS:.o=.dep)
-
-ifneq ($(NO_SECURE),true)
-ifneq ($(NO_DEPS),true)
--include $(CENSUS_LOG_TEST_OBJS:.o=.dep)
-endif
-endif
-
-
 CHANNEL_CREATE_TEST_SRC = \
     test/core/surface/channel_create_test.c \
 
@@ -6554,38 +6570,6 @@
 endif
 
 
-GPR_FILE_TEST_SRC = \
-    test/core/support/file_test.c \
-
-GPR_FILE_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(GPR_FILE_TEST_SRC))))
-ifeq ($(NO_SECURE),true)
-
-# You can't build secure targets if you don't have OpenSSL.
-
-$(BINDIR)/$(CONFIG)/gpr_file_test: openssl_dep_error
-
-else
-
-
-
-$(BINDIR)/$(CONFIG)/gpr_file_test: $(GPR_FILE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
-	$(E) "[LD]      Linking $@"
-	$(Q) mkdir -p `dirname $@`
-	$(Q) $(LD) $(LDFLAGS) $(GPR_FILE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/gpr_file_test
-
-endif
-
-$(OBJDIR)/$(CONFIG)/test/core/support/file_test.o:  $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
-
-deps_gpr_file_test: $(GPR_FILE_TEST_OBJS:.o=.dep)
-
-ifneq ($(NO_SECURE),true)
-ifneq ($(NO_DEPS),true)
--include $(GPR_FILE_TEST_OBJS:.o=.dep)
-endif
-endif
-
-
 GPR_HISTOGRAM_TEST_SRC = \
     test/core/support/histogram_test.c \
 
@@ -6650,6 +6634,38 @@
 endif
 
 
+GPR_LOAD_FILE_TEST_SRC = \
+    test/core/support/load_file_test.c \
+
+GPR_LOAD_FILE_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(GPR_LOAD_FILE_TEST_SRC))))
+ifeq ($(NO_SECURE),true)
+
+# You can't build secure targets if you don't have OpenSSL.
+
+$(BINDIR)/$(CONFIG)/gpr_load_file_test: openssl_dep_error
+
+else
+
+
+
+$(BINDIR)/$(CONFIG)/gpr_load_file_test: $(GPR_LOAD_FILE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+	$(E) "[LD]      Linking $@"
+	$(Q) mkdir -p `dirname $@`
+	$(Q) $(LD) $(LDFLAGS) $(GPR_LOAD_FILE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/gpr_load_file_test
+
+endif
+
+$(OBJDIR)/$(CONFIG)/test/core/support/load_file_test.o:  $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+
+deps_gpr_load_file_test: $(GPR_LOAD_FILE_TEST_OBJS:.o=.dep)
+
+ifneq ($(NO_SECURE),true)
+ifneq ($(NO_DEPS),true)
+-include $(GPR_LOAD_FILE_TEST_OBJS:.o=.dep)
+endif
+endif
+
+
 GPR_LOG_TEST_SRC = \
     test/core/support/log_test.c \
 
@@ -7002,34 +7018,34 @@
 endif
 
 
-GRPC_BASE64_TEST_SRC = \
-    test/core/security/base64_test.c \
+GRPC_B64_TEST_SRC = \
+    test/core/security/b64_test.c \
 
-GRPC_BASE64_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(GRPC_BASE64_TEST_SRC))))
+GRPC_B64_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(GRPC_B64_TEST_SRC))))
 ifeq ($(NO_SECURE),true)
 
 # You can't build secure targets if you don't have OpenSSL.
 
-$(BINDIR)/$(CONFIG)/grpc_base64_test: openssl_dep_error
+$(BINDIR)/$(CONFIG)/grpc_b64_test: openssl_dep_error
 
 else
 
 
 
-$(BINDIR)/$(CONFIG)/grpc_base64_test: $(GRPC_BASE64_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+$(BINDIR)/$(CONFIG)/grpc_b64_test: $(GRPC_B64_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
 	$(E) "[LD]      Linking $@"
 	$(Q) mkdir -p `dirname $@`
-	$(Q) $(LD) $(LDFLAGS) $(GRPC_BASE64_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/grpc_base64_test
+	$(Q) $(LD) $(LDFLAGS) $(GRPC_B64_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/grpc_b64_test
 
 endif
 
-$(OBJDIR)/$(CONFIG)/test/core/security/base64_test.o:  $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+$(OBJDIR)/$(CONFIG)/test/core/security/b64_test.o:  $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
 
-deps_grpc_base64_test: $(GRPC_BASE64_TEST_OBJS:.o=.dep)
+deps_grpc_b64_test: $(GRPC_B64_TEST_OBJS:.o=.dep)
 
 ifneq ($(NO_SECURE),true)
 ifneq ($(NO_DEPS),true)
--include $(GRPC_BASE64_TEST_OBJS:.o=.dep)
+-include $(GRPC_B64_TEST_OBJS:.o=.dep)
 endif
 endif
 
@@ -7962,6 +7978,38 @@
 endif
 
 
+MLOG_TEST_SRC = \
+    test/core/census/mlog_test.c \
+
+MLOG_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(MLOG_TEST_SRC))))
+ifeq ($(NO_SECURE),true)
+
+# You can't build secure targets if you don't have OpenSSL.
+
+$(BINDIR)/$(CONFIG)/mlog_test: openssl_dep_error
+
+else
+
+
+
+$(BINDIR)/$(CONFIG)/mlog_test: $(MLOG_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+	$(E) "[LD]      Linking $@"
+	$(Q) mkdir -p `dirname $@`
+	$(Q) $(LD) $(LDFLAGS) $(MLOG_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/mlog_test
+
+endif
+
+$(OBJDIR)/$(CONFIG)/test/core/census/mlog_test.o:  $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+
+deps_mlog_test: $(MLOG_TEST_OBJS:.o=.dep)
+
+ifneq ($(NO_SECURE),true)
+ifneq ($(NO_DEPS),true)
+-include $(MLOG_TEST_OBJS:.o=.dep)
+endif
+endif
+
+
 MULTIPLE_SERVER_QUEUES_TEST_SRC = \
     test/core/end2end/multiple_server_queues_test.c \
 
@@ -9723,6 +9771,53 @@
 endif
 
 
+GRPCLB_API_TEST_SRC = \
+    $(GENDIR)/src/proto/grpc/lb/v0/load_balancer.pb.cc $(GENDIR)/src/proto/grpc/lb/v0/load_balancer.grpc.pb.cc \
+    test/cpp/grpclb/grpclb_api_test.cc \
+
+GRPCLB_API_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(GRPCLB_API_TEST_SRC))))
+ifeq ($(NO_SECURE),true)
+
+# You can't build secure targets if you don't have OpenSSL.
+
+$(BINDIR)/$(CONFIG)/grpclb_api_test: openssl_dep_error
+
+else
+
+
+
+
+ifeq ($(NO_PROTOBUF),true)
+
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+
+$(BINDIR)/$(CONFIG)/grpclb_api_test: protobuf_dep_error
+
+else
+
+$(BINDIR)/$(CONFIG)/grpclb_api_test: $(PROTOBUF_DEP) $(GRPCLB_API_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a
+	$(E) "[LD]      Linking $@"
+	$(Q) mkdir -p `dirname $@`
+	$(Q) $(LDXX) $(LDFLAGS) $(GRPCLB_API_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/grpclb_api_test
+
+endif
+
+endif
+
+$(OBJDIR)/$(CONFIG)/src/proto/grpc/lb/v0/load_balancer.o:  $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a
+
+$(OBJDIR)/$(CONFIG)/test/cpp/grpclb/grpclb_api_test.o:  $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a
+
+deps_grpclb_api_test: $(GRPCLB_API_TEST_OBJS:.o=.dep)
+
+ifneq ($(NO_SECURE),true)
+ifneq ($(NO_DEPS),true)
+-include $(GRPCLB_API_TEST_OBJS:.o=.dep)
+endif
+endif
+$(OBJDIR)/$(CONFIG)/test/cpp/grpclb/grpclb_api_test.o: $(GENDIR)/src/proto/grpc/lb/v0/load_balancer.pb.cc $(GENDIR)/src/proto/grpc/lb/v0/load_balancer.grpc.pb.cc
+
+
 HYBRID_END2END_TEST_SRC = \
     test/cpp/end2end/hybrid_end2end_test.cc \
 
@@ -12968,7 +13063,7 @@
 # installing headers to their final destination on the drive. We need this
 # otherwise parallel compilation will fail if a source is compiled first.
 src/core/httpcli/httpcli_security_connector.c: $(OPENSSL_DEP)
-src/core/security/base64.c: $(OPENSSL_DEP)
+src/core/security/b64.c: $(OPENSSL_DEP)
 src/core/security/client_auth_filter.c: $(OPENSSL_DEP)
 src/core/security/credentials.c: $(OPENSSL_DEP)
 src/core/security/credentials_metadata.c: $(OPENSSL_DEP)
@@ -12997,7 +13092,7 @@
 src/cpp/server/secure_server_credentials.cc: $(OPENSSL_DEP)
 src/csharp/ext/grpc_csharp_ext.c: $(OPENSSL_DEP)
 test/core/bad_client/bad_client.c: $(OPENSSL_DEP)
-test/core/bad_ssl/server.c: $(OPENSSL_DEP)
+test/core/bad_ssl/server_common.c: $(OPENSSL_DEP)
 test/core/end2end/data/server1_cert.c: $(OPENSSL_DEP)
 test/core/end2end/data/server1_key.c: $(OPENSSL_DEP)
 test/core/end2end/data/test_root_cert.c: $(OPENSSL_DEP)
@@ -13010,8 +13105,8 @@
 test/cpp/interop/client.cc: $(OPENSSL_DEP)
 test/cpp/interop/client_helper.cc: $(OPENSSL_DEP)
 test/cpp/interop/interop_client.cc: $(OPENSSL_DEP)
-test/cpp/interop/server.cc: $(OPENSSL_DEP)
 test/cpp/interop/server_helper.cc: $(OPENSSL_DEP)
+test/cpp/interop/server_main.cc: $(OPENSSL_DEP)
 test/cpp/qps/client_async.cc: $(OPENSSL_DEP)
 test/cpp/qps/client_sync.cc: $(OPENSSL_DEP)
 test/cpp/qps/driver.cc: $(OPENSSL_DEP)
@@ -13021,7 +13116,7 @@
 test/cpp/qps/report.cc: $(OPENSSL_DEP)
 test/cpp/qps/server_async.cc: $(OPENSSL_DEP)
 test/cpp/qps/server_sync.cc: $(OPENSSL_DEP)
-test/cpp/qps/timer.cc: $(OPENSSL_DEP)
+test/cpp/qps/usage_timer.cc: $(OPENSSL_DEP)
 test/cpp/util/benchmark_config.cc: $(OPENSSL_DEP)
 test/cpp/util/byte_buffer_proto_helper.cc: $(OPENSSL_DEP)
 test/cpp/util/cli_call.cc: $(OPENSSL_DEP)
@@ -13029,6 +13124,11 @@
 test/cpp/util/string_ref_helper.cc: $(OPENSSL_DEP)
 test/cpp/util/subprocess.cc: $(OPENSSL_DEP)
 test/cpp/util/test_config.cc: $(OPENSSL_DEP)
+test/cpp/util/test_credentials_provider.cc: $(OPENSSL_DEP)
 endif
 
 .PHONY: all strip tools dep_error openssl_dep_error openssl_dep_message git_update stop buildtests buildtests_c buildtests_cxx test test_c test_cxx install install_c install_cxx install-headers install-headers_c install-headers_cxx install-shared install-shared_c install-shared_cxx install-static install-static_c install-static_cxx strip strip-shared strip-static strip_c strip-shared_c strip-static_c strip_cxx strip-shared_cxx strip-static_cxx dep_c dep_cxx bins_dep_c bins_dep_cxx clean
+
+.PHONY: printvars
+printvars:
+	@$(foreach V,$(sort $(.VARIABLES)),                 	  $(if $(filter-out environment% default automatic, 	  $(origin $V)),$(warning $V=$($V) ($(value $V)))))
diff --git a/PYTHON-MANIFEST.in b/PYTHON-MANIFEST.in
index 072089a..25aba87 100644
--- a/PYTHON-MANIFEST.in
+++ b/PYTHON-MANIFEST.in
@@ -1,4 +1,5 @@
-graft src/python/grpcio/grpc
+recursive-include src/python/grpcio/grpc *.c *.h *.py *.pyx *.pxd *.pxi *.python *.pem
+recursive-exclude src/python/grpcio/grpc/_cython *.so *.pyd
 graft src/python/grpcio/tests
 graft src/core
 graft include/grpc
diff --git a/binding.gyp b/binding.gyp
index a352262..4b5dc4d 100644
--- a/binding.gyp
+++ b/binding.gyp
@@ -504,11 +504,9 @@
         'src/core/support/env_linux.c',
         'src/core/support/env_posix.c',
         'src/core/support/env_win32.c',
-        'src/core/support/file.c',
-        'src/core/support/file_posix.c',
-        'src/core/support/file_win32.c',
         'src/core/support/histogram.c',
         'src/core/support/host_port.c',
+        'src/core/support/load_file.c',
         'src/core/support/log.c',
         'src/core/support/log_android.c',
         'src/core/support/log_linux.c',
@@ -534,6 +532,8 @@
         'src/core/support/time_precise.c',
         'src/core/support/time_win32.c',
         'src/core/support/tls_pthread.c',
+        'src/core/support/tmpfile_posix.c',
+        'src/core/support/tmpfile_win32.c',
         'src/core/support/wrap_memcpy.c',
       ],
       "conditions": [
@@ -558,27 +558,6 @@
         'grpc_codegen_lib',
       ],
       'sources': [
-        'src/core/httpcli/httpcli_security_connector.c',
-        'src/core/security/base64.c',
-        'src/core/security/client_auth_filter.c',
-        'src/core/security/credentials.c',
-        'src/core/security/credentials_metadata.c',
-        'src/core/security/credentials_posix.c',
-        'src/core/security/credentials_win32.c',
-        'src/core/security/google_default_credentials.c',
-        'src/core/security/handshake.c',
-        'src/core/security/json_token.c',
-        'src/core/security/jwt_verifier.c',
-        'src/core/security/secure_endpoint.c',
-        'src/core/security/security_connector.c',
-        'src/core/security/security_context.c',
-        'src/core/security/server_auth_filter.c',
-        'src/core/security/server_secure_chttp2.c',
-        'src/core/surface/init_secure.c',
-        'src/core/surface/secure_channel_create.c',
-        'src/core/tsi/fake_transport_security.c',
-        'src/core/tsi/ssl_transport_security.c',
-        'src/core/tsi/transport_security.c',
         'src/core/census/grpc_context.c',
         'src/core/census/grpc_filter.c',
         'src/core/channel/channel_args.c',
@@ -594,6 +573,7 @@
         'src/core/client_config/connector.c',
         'src/core/client_config/default_initial_connect_string.c',
         'src/core/client_config/initial_connect_string.c',
+        'src/core/client_config/lb_policies/load_balancer_api.c',
         'src/core/client_config/lb_policies/pick_first.c',
         'src/core/client_config/lb_policies/round_robin.c',
         'src/core/client_config/lb_policy.c',
@@ -608,7 +588,7 @@
         'src/core/client_config/subchannel_factory.c',
         'src/core/client_config/subchannel_index.c',
         'src/core/client_config/uri_parser.c',
-        'src/core/compression/algorithm.c',
+        'src/core/compression/compression_algorithm.c',
         'src/core/compression/message_compress.c',
         'src/core/debug/trace.c',
         'src/core/httpcli/format_request.c',
@@ -658,6 +638,7 @@
         'src/core/json/json_reader.c',
         'src/core/json/json_string.c',
         'src/core/json/json_writer.c',
+        'src/core/proto/grpc/lb/v0/load_balancer.pb.c',
         'src/core/surface/alarm.c',
         'src/core/surface/api_trace.c',
         'src/core/surface/byte_buffer.c',
@@ -707,12 +688,36 @@
         'src/core/transport/static_metadata.c',
         'src/core/transport/transport.c',
         'src/core/transport/transport_op_string.c',
+        'src/core/httpcli/httpcli_security_connector.c',
+        'src/core/security/b64.c',
+        'src/core/security/client_auth_filter.c',
+        'src/core/security/credentials.c',
+        'src/core/security/credentials_metadata.c',
+        'src/core/security/credentials_posix.c',
+        'src/core/security/credentials_win32.c',
+        'src/core/security/google_default_credentials.c',
+        'src/core/security/handshake.c',
+        'src/core/security/json_token.c',
+        'src/core/security/jwt_verifier.c',
+        'src/core/security/secure_endpoint.c',
+        'src/core/security/security_connector.c',
+        'src/core/security/security_context.c',
+        'src/core/security/server_auth_filter.c',
+        'src/core/security/server_secure_chttp2.c',
+        'src/core/surface/init_secure.c',
+        'src/core/surface/secure_channel_create.c',
+        'src/core/tsi/fake_transport_security.c',
+        'src/core/tsi/ssl_transport_security.c',
+        'src/core/tsi/transport_security.c',
         'src/core/census/context.c',
         'src/core/census/initialize.c',
-        'src/core/census/log.c',
+        'src/core/census/mlog.c',
         'src/core/census/operation.c',
         'src/core/census/placeholders.c',
         'src/core/census/tracing.c',
+        'third_party/nanopb/pb_common.c',
+        'third_party/nanopb/pb_decode.c',
+        'third_party/nanopb/pb_encode.c',
       ],
       "conditions": [
         ['OS == "mac"', {
diff --git a/build.yaml b/build.yaml
index bd84ff3..9c946a8 100644
--- a/build.yaml
+++ b/build.yaml
@@ -14,12 +14,12 @@
   - include/grpc/census.h
   headers:
   - src/core/census/aggregation.h
-  - src/core/census/log.h
+  - src/core/census/mlog.h
   - src/core/census/rpc_metric_id.h
   src:
   - src/core/census/context.c
   - src/core/census/initialize.c
-  - src/core/census/log.c
+  - src/core/census/mlog.c
   - src/core/census/operation.c
   - src/core/census/placeholders.c
   - src/core/census/tracing.c
@@ -57,13 +57,14 @@
   - src/core/profiling/timers.h
   - src/core/support/block_annotate.h
   - src/core/support/env.h
-  - src/core/support/file.h
+  - src/core/support/load_file.h
   - src/core/support/murmur_hash.h
   - src/core/support/stack_lockfree.h
   - src/core/support/string.h
   - src/core/support/string_win32.h
   - src/core/support/thd_internal.h
   - src/core/support/time_precise.h
+  - src/core/support/tmpfile.h
   src:
   - src/core/profiling/basic_timers.c
   - src/core/profiling/stap_timers.c
@@ -77,11 +78,9 @@
   - src/core/support/env_linux.c
   - src/core/support/env_posix.c
   - src/core/support/env_win32.c
-  - src/core/support/file.c
-  - src/core/support/file_posix.c
-  - src/core/support/file_win32.c
   - src/core/support/histogram.c
   - src/core/support/host_port.c
+  - src/core/support/load_file.c
   - src/core/support/log.c
   - src/core/support/log_android.c
   - src/core/support/log_linux.c
@@ -107,6 +106,8 @@
   - src/core/support/time_precise.c
   - src/core/support/time_win32.c
   - src/core/support/tls_pthread.c
+  - src/core/support/tmpfile_posix.c
+  - src/core/support/tmpfile_win32.c
   - src/core/support/wrap_memcpy.c
 - name: gpr_codegen
   public_headers:
@@ -183,11 +184,11 @@
   - src/cpp/client/credentials.cc
   - src/cpp/client/generic_stub.cc
   - src/cpp/client/insecure_credentials.cc
-  - src/cpp/common/alarm.cc
   - src/cpp/common/call.cc
   - src/cpp/common/channel_arguments.cc
   - src/cpp/common/completion_queue.cc
   - src/cpp/common/rpc_method.cc
+  - src/cpp/proto/proto_serializer.cc
   - src/cpp/proto/proto_utils.cc
   - src/cpp/server/async_generic_service.cc
   - src/cpp/server/create_default_thread_pool.cc
@@ -224,6 +225,7 @@
   - src/core/client_config/client_config.h
   - src/core/client_config/connector.h
   - src/core/client_config/initial_connect_string.h
+  - src/core/client_config/lb_policies/load_balancer_api.h
   - src/core/client_config/lb_policies/pick_first.h
   - src/core/client_config/lb_policies/round_robin.h
   - src/core/client_config/lb_policy.h
@@ -274,7 +276,6 @@
   - src/core/iomgr/time_averaged_stats.h
   - src/core/iomgr/timer.h
   - src/core/iomgr/timer_heap.h
-  - src/core/iomgr/timer_internal.h
   - src/core/iomgr/udp_server.h
   - src/core/iomgr/wakeup_fd_pipe.h
   - src/core/iomgr/wakeup_fd_posix.h
@@ -285,6 +286,7 @@
   - src/core/json/json_common.h
   - src/core/json/json_reader.h
   - src/core/json/json_writer.h
+  - src/core/proto/grpc/lb/v0/load_balancer.pb.h
   - src/core/statistics/census_interface.h
   - src/core/statistics/census_rpc_stats.h
   - src/core/surface/api_trace.h
@@ -340,6 +342,7 @@
   - src/core/client_config/connector.c
   - src/core/client_config/default_initial_connect_string.c
   - src/core/client_config/initial_connect_string.c
+  - src/core/client_config/lb_policies/load_balancer_api.c
   - src/core/client_config/lb_policies/pick_first.c
   - src/core/client_config/lb_policies/round_robin.c
   - src/core/client_config/lb_policy.c
@@ -354,7 +357,7 @@
   - src/core/client_config/subchannel_factory.c
   - src/core/client_config/subchannel_index.c
   - src/core/client_config/uri_parser.c
-  - src/core/compression/algorithm.c
+  - src/core/compression/compression_algorithm.c
   - src/core/compression/message_compress.c
   - src/core/debug/trace.c
   - src/core/httpcli/format_request.c
@@ -404,6 +407,7 @@
   - src/core/json/json_reader.c
   - src/core/json/json_string.c
   - src/core/json/json_writer.c
+  - src/core/proto/grpc/lb/v0/load_balancer.pb.c
   - src/core/surface/alarm.c
   - src/core/surface/api_trace.c
   - src/core/surface/byte_buffer.c
@@ -453,6 +457,44 @@
   - src/core/transport/static_metadata.c
   - src/core/transport/transport.c
   - src/core/transport/transport_op_string.c
+- name: grpc_secure
+  headers:
+  - src/core/security/auth_filters.h
+  - src/core/security/b64.h
+  - src/core/security/credentials.h
+  - src/core/security/handshake.h
+  - src/core/security/json_token.h
+  - src/core/security/jwt_verifier.h
+  - src/core/security/secure_endpoint.h
+  - src/core/security/security_connector.h
+  - src/core/security/security_context.h
+  - src/core/tsi/fake_transport_security.h
+  - src/core/tsi/ssl_transport_security.h
+  - src/core/tsi/ssl_types.h
+  - src/core/tsi/transport_security.h
+  - src/core/tsi/transport_security_interface.h
+  src:
+  - src/core/httpcli/httpcli_security_connector.c
+  - src/core/security/b64.c
+  - src/core/security/client_auth_filter.c
+  - src/core/security/credentials.c
+  - src/core/security/credentials_metadata.c
+  - src/core/security/credentials_posix.c
+  - src/core/security/credentials_win32.c
+  - src/core/security/google_default_credentials.c
+  - src/core/security/handshake.c
+  - src/core/security/json_token.c
+  - src/core/security/jwt_verifier.c
+  - src/core/security/secure_endpoint.c
+  - src/core/security/security_connector.c
+  - src/core/security/security_context.c
+  - src/core/security/server_auth_filter.c
+  - src/core/security/server_secure_chttp2.c
+  - src/core/surface/init_secure.c
+  - src/core/surface/secure_channel_create.c
+  - src/core/tsi/fake_transport_security.c
+  - src/core/tsi/ssl_transport_security.c
+  - src/core/tsi/transport_security.c
 - name: grpc_test_util_base
   headers:
   - test/core/end2end/cq_verifier.h
@@ -471,6 +513,16 @@
   - test/core/util/port_posix.c
   - test/core/util/port_windows.c
   - test/core/util/slice_splitter.c
+- name: nanopb
+  headers:
+  - third_party/nanopb/pb.h
+  - third_party/nanopb/pb_common.h
+  - third_party/nanopb/pb_decode.h
+  - third_party/nanopb/pb_encode.h
+  src:
+  - third_party/nanopb/pb_common.c
+  - third_party/nanopb/pb_decode.c
+  - third_party/nanopb/pb_encode.c
 libs:
 - name: gpr
   build: all
@@ -496,43 +548,6 @@
   language: c
   public_headers:
   - include/grpc/grpc_security.h
-  headers:
-  - src/core/security/auth_filters.h
-  - src/core/security/base64.h
-  - src/core/security/credentials.h
-  - src/core/security/handshake.h
-  - src/core/security/json_token.h
-  - src/core/security/jwt_verifier.h
-  - src/core/security/secure_endpoint.h
-  - src/core/security/security_connector.h
-  - src/core/security/security_context.h
-  - src/core/tsi/fake_transport_security.h
-  - src/core/tsi/ssl_transport_security.h
-  - src/core/tsi/ssl_types.h
-  - src/core/tsi/transport_security.h
-  - src/core/tsi/transport_security_interface.h
-  src:
-  - src/core/httpcli/httpcli_security_connector.c
-  - src/core/security/base64.c
-  - src/core/security/client_auth_filter.c
-  - src/core/security/credentials.c
-  - src/core/security/credentials_metadata.c
-  - src/core/security/credentials_posix.c
-  - src/core/security/credentials_win32.c
-  - src/core/security/google_default_credentials.c
-  - src/core/security/handshake.c
-  - src/core/security/json_token.c
-  - src/core/security/jwt_verifier.c
-  - src/core/security/secure_endpoint.c
-  - src/core/security/security_connector.c
-  - src/core/security/security_context.c
-  - src/core/security/server_auth_filter.c
-  - src/core/security/server_secure_chttp2.c
-  - src/core/surface/init_secure.c
-  - src/core/surface/secure_channel_create.c
-  - src/core/tsi/fake_transport_security.c
-  - src/core/tsi/ssl_transport_security.c
-  - src/core/tsi/transport_security.c
   deps:
   - gpr
   - grpc_codegen_lib
@@ -541,7 +556,9 @@
   dll: true
   filegroups:
   - grpc_base
+  - grpc_secure
   - census
+  - nanopb
   secure: true
   vs_packages:
   - grpc.dependencies.openssl
@@ -563,6 +580,27 @@
   - gpr_codegen
   secure: false
   vs_project_guid: '{A828FD72-44CE-4EA5-8966-6E4624458D58}'
+- name: grpc_dll
+  build: private
+  language: c
+  src: []
+  deps:
+  - gpr
+  - grpc
+  build_system:
+  - visual_studio
+  deps_linkage: static
+  dll_def: grpc.def
+  vs_config_type: DynamicLibrary
+  vs_packages:
+  - grpc.dependencies.openssl
+  - grpc.dependencies.zlib
+  vs_project_guid: '{A2F6CBBA-A553-41B3-A7DE-F26DECCC27F0}'
+  vs_props:
+  - zlib
+  - openssl
+  - winsock
+  - global
 - name: grpc_test_util
   build: private
   language: c
@@ -606,6 +644,7 @@
   filegroups:
   - grpc_base
   - census
+  - nanopb
   secure: false
   vs_project_guid: '{46CEDFFF-9692-456A-AA24-38B5D6BCF4C5}'
 - name: grpc_zookeeper
@@ -733,6 +772,7 @@
   - test/cpp/util/create_test_channel.h
   - test/cpp/util/string_ref_helper.h
   - test/cpp/util/subprocess.h
+  - test/cpp/util/test_credentials_provider.h
   src:
   - src/proto/grpc/testing/echo_messages.proto
   - src/proto/grpc/testing/echo.proto
@@ -743,6 +783,7 @@
   - test/cpp/util/create_test_channel.cc
   - test/cpp/util/string_ref_helper.cc
   - test/cpp/util/subprocess.cc
+  - test/cpp/util/test_credentials_provider.cc
   deps:
   - grpc++
   - grpc_test_util
@@ -793,6 +834,8 @@
   - gpr_codegen
   secure: false
   vs_project_guid: '{B6E81D84-2ACB-41B8-8781-493A944C7817}'
+  vs_props:
+  - protoc
 - name: interop_client_helper
   build: private
   language: c++
@@ -846,7 +889,7 @@
   - src/proto/grpc/testing/empty.proto
   - src/proto/grpc/testing/messages.proto
   - src/proto/grpc/testing/test.proto
-  - test/cpp/interop/server.cc
+  - test/cpp/interop/server_main.cc
   deps:
   - interop_server_helper
   - grpc++_test_util
@@ -870,7 +913,7 @@
   - test/cpp/qps/report.h
   - test/cpp/qps/server.h
   - test/cpp/qps/stats.h
-  - test/cpp/qps/timer.h
+  - test/cpp/qps/usage_timer.h
   - test/cpp/util/benchmark_config.h
   src:
   - src/proto/grpc/testing/messages.proto
@@ -888,7 +931,7 @@
   - test/cpp/qps/report.cc
   - test/cpp/qps/server_async.cc
   - test/cpp/qps/server_sync.cc
-  - test/cpp/qps/timer.cc
+  - test/cpp/qps/usage_timer.cc
   - test/cpp/util/benchmark_config.cc
   deps:
   - grpc_test_util
@@ -972,16 +1015,6 @@
   - grpc
   - gpr_test_util
   - gpr
-- name: census_log_test
-  build: test
-  language: c
-  src:
-  - test/core/census/log_test.c
-  deps:
-  - grpc_test_util
-  - grpc
-  - gpr_test_util
-  - gpr
 - name: channel_create_test
   build: test
   language: c
@@ -1203,14 +1236,6 @@
   deps:
   - gpr_test_util
   - gpr
-- name: gpr_file_test
-  build: test
-  language: c
-  src:
-  - test/core/support/file_test.c
-  deps:
-  - gpr_test_util
-  - gpr
 - name: gpr_histogram_test
   build: test
   language: c
@@ -1227,6 +1252,14 @@
   deps:
   - gpr_test_util
   - gpr
+- name: gpr_load_file_test
+  build: test
+  language: c
+  src:
+  - test/core/support/load_file_test.c
+  deps:
+  - gpr_test_util
+  - gpr
 - name: gpr_log_test
   build: test
   language: c
@@ -1320,11 +1353,11 @@
   - grpc
   - gpr_test_util
   - gpr
-- name: grpc_base64_test
+- name: grpc_b64_test
   build: test
   language: c
   src:
-  - test/core/security/base64_test.c
+  - test/core/security/b64_test.c
   deps:
   - grpc_test_util
   - grpc
@@ -1636,6 +1669,16 @@
   - grpc
   - gpr_test_util
   - gpr
+- name: mlog_test
+  build: test
+  language: c
+  src:
+  - test/core/census/mlog_test.c
+  deps:
+  - grpc_test_util
+  - grpc
+  - gpr_test_util
+  - gpr
 - name: multiple_server_queues_test
   build: test
   language: c
@@ -1928,6 +1971,7 @@
   - linux
   - posix
 - name: alarm_cpp_test
+  gtest: true
   build: test
   language: c++
   src:
@@ -1940,6 +1984,7 @@
   - gpr_test_util
   - gpr
 - name: async_end2end_test
+  gtest: true
   build: test
   language: c++
   src:
@@ -1986,6 +2031,7 @@
   - linux
   - posix
 - name: auth_property_iterator_test
+  gtest: true
   build: test
   language: c++
   src:
@@ -1998,6 +2044,7 @@
   - gpr_test_util
   - gpr
 - name: channel_arguments_test
+  gtest: true
   build: test
   language: c++
   src:
@@ -2007,6 +2054,7 @@
   - grpc
   - gpr
 - name: cli_call_test
+  gtest: true
   build: test
   language: c++
   src:
@@ -2019,6 +2067,7 @@
   - gpr_test_util
   - gpr
 - name: client_crash_test
+  gtest: true
   cpu_cost: 0.1
   build: test
   language: c++
@@ -2049,6 +2098,7 @@
   - gpr_test_util
   - gpr
 - name: credentials_test
+  gtest: true
   build: test
   language: c++
   src:
@@ -2058,6 +2108,7 @@
   - grpc
   - gpr
 - name: cxx_byte_buffer_test
+  gtest: true
   build: test
   language: c++
   src:
@@ -2069,6 +2120,7 @@
   - gpr_test_util
   - gpr
 - name: cxx_slice_test
+  gtest: true
   build: test
   language: c++
   src:
@@ -2080,6 +2132,7 @@
   - gpr_test_util
   - gpr
 - name: cxx_string_ref_test
+  gtest: true
   build: test
   language: c++
   src:
@@ -2087,6 +2140,7 @@
   deps:
   - grpc++
 - name: cxx_time_test
+  gtest: true
   build: test
   language: c++
   src:
@@ -2098,6 +2152,7 @@
   - gpr_test_util
   - gpr
 - name: end2end_test
+  gtest: true
   cpu_cost: 0.5
   build: test
   language: c++
@@ -2128,6 +2183,7 @@
   - linux
   - posix
 - name: generic_end2end_test
+  gtest: true
   build: test
   language: c++
   src:
@@ -2203,7 +2259,20 @@
   secure: false
   vs_config_type: Application
   vs_project_guid: '{069E9D05-B78B-4751-9252-D21EBAE7DE8E}'
+- name: grpclb_api_test
+  gtest: true
+  build: test
+  language: c++
+  src:
+  - src/proto/grpc/lb/v0/load_balancer.proto
+  - test/cpp/grpclb/grpclb_api_test.cc
+  deps:
+  - grpc++_test_util
+  - grpc_test_util
+  - grpc++
+  - grpc
 - name: hybrid_end2end_test
+  gtest: true
   build: test
   language: c++
   src:
@@ -2283,6 +2352,7 @@
   - gpr
   - grpc++_test_config
 - name: mock_test
+  gtest: true
   build: test
   language: c++
   src:
@@ -2327,6 +2397,7 @@
   - linux
   - posix
 - name: qps_openloop_test
+  cpu_cost: 10
   build: test
   language: c++
   src:
@@ -2359,8 +2430,6 @@
   - gpr_test_util
   - gpr
   - grpc++_test_config
-  exclude_configs:
-  - tsan
   platforms:
   - mac
   - linux
@@ -2419,6 +2488,7 @@
   - gpr
   - grpc++_test_config
 - name: secure_auth_context_test
+  gtest: true
   build: test
   language: c++
   src:
@@ -2448,6 +2518,7 @@
   - linux
   - posix
 - name: server_crash_test
+  gtest: true
   cpu_cost: 0.1
   build: test
   language: c++
@@ -2478,6 +2549,7 @@
   - gpr_test_util
   - gpr
 - name: shutdown_test
+  gtest: true
   build: test
   language: c++
   src:
@@ -2501,6 +2573,7 @@
   - gpr_test_util
   - gpr
 - name: streaming_throughput_test
+  gtest: true
   build: test
   language: c++
   src:
@@ -2577,6 +2650,7 @@
   - linux
   - posix
 - name: thread_stress_test
+  gtest: true
   cpu_cost: 100
   build: test
   language: c++
@@ -2590,6 +2664,7 @@
   - gpr_test_util
   - gpr
 - name: zookeeper_test
+  gtest: true
   build: test
   run: false
   language: c++
@@ -2648,7 +2723,7 @@
     test_environ:
       ASAN_OPTIONS: detect_leaks=1:color=always
       LSAN_OPTIONS: suppressions=tools/lsan_suppressions.txt:report_objects=1
-    timeout_multiplier: 1.5
+    timeout_multiplier: 3
   asan-noleaks:
     CC: clang
     CPPFLAGS: -O0 -fsanitize=address -fno-omit-frame-pointer -Wno-unused-command-line-argument
@@ -2660,7 +2735,7 @@
     compile_the_world: true
     test_environ:
       ASAN_OPTIONS: detect_leaks=0:color=always
-    timeout_multiplier: 1.5
+    timeout_multiplier: 3
   basicprof:
     CPPFLAGS: -O2 -DGRPC_BASIC_PROFILER -DGRPC_TIMERS_RDTSC
     DEFINES: NDEBUG
@@ -2699,7 +2774,7 @@
       -fPIE -pie $(if $(JENKINS_BUILD),-Wl$(comma)-Ttext-segment=0x7e0000000000,)
     LDXX: clang++
     compile_the_world: true
-    timeout_multiplier: 2
+    timeout_multiplier: 4
   mutrace:
     CPPFLAGS: -O0
     DEFINES: _DEBUG DEBUG
@@ -2721,7 +2796,7 @@
     compile_the_world: true
     test_environ:
       TSAN_OPTIONS: suppressions=tools/tsan_suppressions.txt:halt_on_error=1:second_deadlock_stack=1
-    timeout_multiplier: 2
+    timeout_multiplier: 5
   ubsan:
     CC: clang
     CPPFLAGS: -O1 -fsanitize=undefined -fno-omit-frame-pointer -Wno-unused-command-line-argument
@@ -2780,6 +2855,37 @@
   - src/node/ext/server.cc
   - src/node/ext/server_credentials.cc
   - src/node/ext/timeval.cc
+openssl_fallback:
+  base_uri: http://openssl.org/source/
+  extraction_dir: openssl-1.0.2f
+  tarball: openssl-1.0.2f.tar.gz
+php_config_m4:
+  deps:
+  - grpc
+  - gpr
+  - boringssl
+  headers:
+  - src/php/ext/grpc/byte_buffer.h
+  - src/php/ext/grpc/call.h
+  - src/php/ext/grpc/call_credentials.h
+  - src/php/ext/grpc/channel.h
+  - src/php/ext/grpc/channel_credentials.h
+  - src/php/ext/grpc/completion_queue.h
+  - src/php/ext/grpc/php_grpc.h
+  - src/php/ext/grpc/server.h
+  - src/php/ext/grpc/server_credentials.h
+  - src/php/ext/grpc/timeval.h
+  src:
+  - src/php/ext/grpc/byte_buffer.c
+  - src/php/ext/grpc/call.c
+  - src/php/ext/grpc/call_credentials.c
+  - src/php/ext/grpc/channel.c
+  - src/php/ext/grpc/channel_credentials.c
+  - src/php/ext/grpc/completion_queue.c
+  - src/php/ext/grpc/php_grpc.c
+  - src/php/ext/grpc/server.c
+  - src/php/ext/grpc/server_credentials.c
+  - src/php/ext/grpc/timeval.c
 python_dependencies:
   deps:
   - grpc
diff --git a/config.m4 b/config.m4
new file mode 100644
index 0000000..8ab45e6
--- /dev/null
+++ b/config.m4
@@ -0,0 +1,606 @@
+PHP_ARG_ENABLE(grpc, whether to enable grpc support,
+[  --enable-grpc           Enable grpc support])
+
+if test "$PHP_GRPC" != "no"; then
+  dnl Write more examples of tests here...
+
+  dnl # --with-grpc -> add include path
+  PHP_ADD_INCLUDE(../../grpc/include)
+  PHP_ADD_INCLUDE(../../grpc/src/php/ext/grpc)
+  PHP_ADD_INCLUDE(../../grpc/third_party/boringssl/include)
+
+  LIBS="-lpthread $LIBS"
+
+  GRPC_SHARED_LIBADD="-lpthread $GRPC_SHARED_LIBADD"
+  PHP_ADD_LIBRARY(pthread)
+
+  PHP_ADD_LIBRARY(dl,,GRPC_SHARED_LIBADD)
+  PHP_ADD_LIBRARY(dl)
+
+  case $host in
+    *darwin*) ;;
+    *)
+      PHP_ADD_LIBRARY(rt,,GRPC_SHARED_LIBADD)
+      PHP_ADD_LIBRARY(rt)
+      ;;
+  esac
+
+  PHP_NEW_EXTENSION(grpc,
+    src/php/ext/grpc/byte_buffer.c \
+    src/php/ext/grpc/call.c \
+    src/php/ext/grpc/call_credentials.c \
+    src/php/ext/grpc/channel.c \
+    src/php/ext/grpc/channel_credentials.c \
+    src/php/ext/grpc/completion_queue.c \
+    src/php/ext/grpc/php_grpc.c \
+    src/php/ext/grpc/server.c \
+    src/php/ext/grpc/server_credentials.c \
+    src/php/ext/grpc/timeval.c \
+    src/core/profiling/basic_timers.c \
+    src/core/profiling/stap_timers.c \
+    src/core/support/alloc.c \
+    src/core/support/avl.c \
+    src/core/support/cmdline.c \
+    src/core/support/cpu_iphone.c \
+    src/core/support/cpu_linux.c \
+    src/core/support/cpu_posix.c \
+    src/core/support/cpu_windows.c \
+    src/core/support/env_linux.c \
+    src/core/support/env_posix.c \
+    src/core/support/env_win32.c \
+    src/core/support/histogram.c \
+    src/core/support/host_port.c \
+    src/core/support/load_file.c \
+    src/core/support/log.c \
+    src/core/support/log_android.c \
+    src/core/support/log_linux.c \
+    src/core/support/log_posix.c \
+    src/core/support/log_win32.c \
+    src/core/support/murmur_hash.c \
+    src/core/support/slice.c \
+    src/core/support/slice_buffer.c \
+    src/core/support/stack_lockfree.c \
+    src/core/support/string.c \
+    src/core/support/string_posix.c \
+    src/core/support/string_win32.c \
+    src/core/support/subprocess_posix.c \
+    src/core/support/subprocess_windows.c \
+    src/core/support/sync.c \
+    src/core/support/sync_posix.c \
+    src/core/support/sync_win32.c \
+    src/core/support/thd.c \
+    src/core/support/thd_posix.c \
+    src/core/support/thd_win32.c \
+    src/core/support/time.c \
+    src/core/support/time_posix.c \
+    src/core/support/time_precise.c \
+    src/core/support/time_win32.c \
+    src/core/support/tls_pthread.c \
+    src/core/support/tmpfile_posix.c \
+    src/core/support/tmpfile_win32.c \
+    src/core/support/wrap_memcpy.c \
+    src/core/census/grpc_context.c \
+    src/core/census/grpc_filter.c \
+    src/core/channel/channel_args.c \
+    src/core/channel/channel_stack.c \
+    src/core/channel/client_channel.c \
+    src/core/channel/client_uchannel.c \
+    src/core/channel/compress_filter.c \
+    src/core/channel/connected_channel.c \
+    src/core/channel/http_client_filter.c \
+    src/core/channel/http_server_filter.c \
+    src/core/channel/subchannel_call_holder.c \
+    src/core/client_config/client_config.c \
+    src/core/client_config/connector.c \
+    src/core/client_config/default_initial_connect_string.c \
+    src/core/client_config/initial_connect_string.c \
+    src/core/client_config/lb_policies/load_balancer_api.c \
+    src/core/client_config/lb_policies/pick_first.c \
+    src/core/client_config/lb_policies/round_robin.c \
+    src/core/client_config/lb_policy.c \
+    src/core/client_config/lb_policy_factory.c \
+    src/core/client_config/lb_policy_registry.c \
+    src/core/client_config/resolver.c \
+    src/core/client_config/resolver_factory.c \
+    src/core/client_config/resolver_registry.c \
+    src/core/client_config/resolvers/dns_resolver.c \
+    src/core/client_config/resolvers/sockaddr_resolver.c \
+    src/core/client_config/subchannel.c \
+    src/core/client_config/subchannel_factory.c \
+    src/core/client_config/subchannel_index.c \
+    src/core/client_config/uri_parser.c \
+    src/core/compression/compression_algorithm.c \
+    src/core/compression/message_compress.c \
+    src/core/debug/trace.c \
+    src/core/httpcli/format_request.c \
+    src/core/httpcli/httpcli.c \
+    src/core/httpcli/parser.c \
+    src/core/iomgr/closure.c \
+    src/core/iomgr/endpoint.c \
+    src/core/iomgr/endpoint_pair_posix.c \
+    src/core/iomgr/endpoint_pair_windows.c \
+    src/core/iomgr/exec_ctx.c \
+    src/core/iomgr/executor.c \
+    src/core/iomgr/fd_posix.c \
+    src/core/iomgr/iocp_windows.c \
+    src/core/iomgr/iomgr.c \
+    src/core/iomgr/iomgr_posix.c \
+    src/core/iomgr/iomgr_windows.c \
+    src/core/iomgr/pollset_multipoller_with_epoll.c \
+    src/core/iomgr/pollset_multipoller_with_poll_posix.c \
+    src/core/iomgr/pollset_posix.c \
+    src/core/iomgr/pollset_set_posix.c \
+    src/core/iomgr/pollset_set_windows.c \
+    src/core/iomgr/pollset_windows.c \
+    src/core/iomgr/resolve_address_posix.c \
+    src/core/iomgr/resolve_address_windows.c \
+    src/core/iomgr/sockaddr_utils.c \
+    src/core/iomgr/socket_utils_common_posix.c \
+    src/core/iomgr/socket_utils_linux.c \
+    src/core/iomgr/socket_utils_posix.c \
+    src/core/iomgr/socket_windows.c \
+    src/core/iomgr/tcp_client_posix.c \
+    src/core/iomgr/tcp_client_windows.c \
+    src/core/iomgr/tcp_posix.c \
+    src/core/iomgr/tcp_server_posix.c \
+    src/core/iomgr/tcp_server_windows.c \
+    src/core/iomgr/tcp_windows.c \
+    src/core/iomgr/time_averaged_stats.c \
+    src/core/iomgr/timer.c \
+    src/core/iomgr/timer_heap.c \
+    src/core/iomgr/udp_server.c \
+    src/core/iomgr/wakeup_fd_eventfd.c \
+    src/core/iomgr/wakeup_fd_nospecial.c \
+    src/core/iomgr/wakeup_fd_pipe.c \
+    src/core/iomgr/wakeup_fd_posix.c \
+    src/core/iomgr/workqueue_posix.c \
+    src/core/iomgr/workqueue_windows.c \
+    src/core/json/json.c \
+    src/core/json/json_reader.c \
+    src/core/json/json_string.c \
+    src/core/json/json_writer.c \
+    src/core/proto/grpc/lb/v0/load_balancer.pb.c \
+    src/core/surface/alarm.c \
+    src/core/surface/api_trace.c \
+    src/core/surface/byte_buffer.c \
+    src/core/surface/byte_buffer_reader.c \
+    src/core/surface/call.c \
+    src/core/surface/call_details.c \
+    src/core/surface/call_log_batch.c \
+    src/core/surface/channel.c \
+    src/core/surface/channel_connectivity.c \
+    src/core/surface/channel_create.c \
+    src/core/surface/channel_ping.c \
+    src/core/surface/completion_queue.c \
+    src/core/surface/event_string.c \
+    src/core/surface/init.c \
+    src/core/surface/lame_client.c \
+    src/core/surface/metadata_array.c \
+    src/core/surface/server.c \
+    src/core/surface/server_chttp2.c \
+    src/core/surface/server_create.c \
+    src/core/surface/validate_metadata.c \
+    src/core/surface/version.c \
+    src/core/transport/byte_stream.c \
+    src/core/transport/chttp2/alpn.c \
+    src/core/transport/chttp2/bin_encoder.c \
+    src/core/transport/chttp2/frame_data.c \
+    src/core/transport/chttp2/frame_goaway.c \
+    src/core/transport/chttp2/frame_ping.c \
+    src/core/transport/chttp2/frame_rst_stream.c \
+    src/core/transport/chttp2/frame_settings.c \
+    src/core/transport/chttp2/frame_window_update.c \
+    src/core/transport/chttp2/hpack_encoder.c \
+    src/core/transport/chttp2/hpack_parser.c \
+    src/core/transport/chttp2/hpack_table.c \
+    src/core/transport/chttp2/huffsyms.c \
+    src/core/transport/chttp2/incoming_metadata.c \
+    src/core/transport/chttp2/parsing.c \
+    src/core/transport/chttp2/status_conversion.c \
+    src/core/transport/chttp2/stream_lists.c \
+    src/core/transport/chttp2/stream_map.c \
+    src/core/transport/chttp2/timeout_encoding.c \
+    src/core/transport/chttp2/varint.c \
+    src/core/transport/chttp2/writing.c \
+    src/core/transport/chttp2_transport.c \
+    src/core/transport/connectivity_state.c \
+    src/core/transport/metadata.c \
+    src/core/transport/metadata_batch.c \
+    src/core/transport/static_metadata.c \
+    src/core/transport/transport.c \
+    src/core/transport/transport_op_string.c \
+    src/core/httpcli/httpcli_security_connector.c \
+    src/core/security/b64.c \
+    src/core/security/client_auth_filter.c \
+    src/core/security/credentials.c \
+    src/core/security/credentials_metadata.c \
+    src/core/security/credentials_posix.c \
+    src/core/security/credentials_win32.c \
+    src/core/security/google_default_credentials.c \
+    src/core/security/handshake.c \
+    src/core/security/json_token.c \
+    src/core/security/jwt_verifier.c \
+    src/core/security/secure_endpoint.c \
+    src/core/security/security_connector.c \
+    src/core/security/security_context.c \
+    src/core/security/server_auth_filter.c \
+    src/core/security/server_secure_chttp2.c \
+    src/core/surface/init_secure.c \
+    src/core/surface/secure_channel_create.c \
+    src/core/tsi/fake_transport_security.c \
+    src/core/tsi/ssl_transport_security.c \
+    src/core/tsi/transport_security.c \
+    src/core/census/context.c \
+    src/core/census/initialize.c \
+    src/core/census/mlog.c \
+    src/core/census/operation.c \
+    src/core/census/placeholders.c \
+    src/core/census/tracing.c \
+    third_party/nanopb/pb_common.c \
+    third_party/nanopb/pb_decode.c \
+    third_party/nanopb/pb_encode.c \
+    src/boringssl/err_data.c \
+    third_party/boringssl/crypto/aes/aes.c \
+    third_party/boringssl/crypto/aes/mode_wrappers.c \
+    third_party/boringssl/crypto/asn1/a_bitstr.c \
+    third_party/boringssl/crypto/asn1/a_bool.c \
+    third_party/boringssl/crypto/asn1/a_bytes.c \
+    third_party/boringssl/crypto/asn1/a_d2i_fp.c \
+    third_party/boringssl/crypto/asn1/a_dup.c \
+    third_party/boringssl/crypto/asn1/a_enum.c \
+    third_party/boringssl/crypto/asn1/a_gentm.c \
+    third_party/boringssl/crypto/asn1/a_i2d_fp.c \
+    third_party/boringssl/crypto/asn1/a_int.c \
+    third_party/boringssl/crypto/asn1/a_mbstr.c \
+    third_party/boringssl/crypto/asn1/a_object.c \
+    third_party/boringssl/crypto/asn1/a_octet.c \
+    third_party/boringssl/crypto/asn1/a_print.c \
+    third_party/boringssl/crypto/asn1/a_strnid.c \
+    third_party/boringssl/crypto/asn1/a_time.c \
+    third_party/boringssl/crypto/asn1/a_type.c \
+    third_party/boringssl/crypto/asn1/a_utctm.c \
+    third_party/boringssl/crypto/asn1/a_utf8.c \
+    third_party/boringssl/crypto/asn1/asn1_lib.c \
+    third_party/boringssl/crypto/asn1/asn1_par.c \
+    third_party/boringssl/crypto/asn1/asn_pack.c \
+    third_party/boringssl/crypto/asn1/bio_asn1.c \
+    third_party/boringssl/crypto/asn1/bio_ndef.c \
+    third_party/boringssl/crypto/asn1/f_enum.c \
+    third_party/boringssl/crypto/asn1/f_int.c \
+    third_party/boringssl/crypto/asn1/f_string.c \
+    third_party/boringssl/crypto/asn1/t_bitst.c \
+    third_party/boringssl/crypto/asn1/t_pkey.c \
+    third_party/boringssl/crypto/asn1/tasn_dec.c \
+    third_party/boringssl/crypto/asn1/tasn_enc.c \
+    third_party/boringssl/crypto/asn1/tasn_fre.c \
+    third_party/boringssl/crypto/asn1/tasn_new.c \
+    third_party/boringssl/crypto/asn1/tasn_prn.c \
+    third_party/boringssl/crypto/asn1/tasn_typ.c \
+    third_party/boringssl/crypto/asn1/tasn_utl.c \
+    third_party/boringssl/crypto/asn1/x_bignum.c \
+    third_party/boringssl/crypto/asn1/x_long.c \
+    third_party/boringssl/crypto/base64/base64.c \
+    third_party/boringssl/crypto/bio/bio.c \
+    third_party/boringssl/crypto/bio/bio_mem.c \
+    third_party/boringssl/crypto/bio/buffer.c \
+    third_party/boringssl/crypto/bio/connect.c \
+    third_party/boringssl/crypto/bio/fd.c \
+    third_party/boringssl/crypto/bio/file.c \
+    third_party/boringssl/crypto/bio/hexdump.c \
+    third_party/boringssl/crypto/bio/pair.c \
+    third_party/boringssl/crypto/bio/printf.c \
+    third_party/boringssl/crypto/bio/socket.c \
+    third_party/boringssl/crypto/bio/socket_helper.c \
+    third_party/boringssl/crypto/bn/add.c \
+    third_party/boringssl/crypto/bn/asm/x86_64-gcc.c \
+    third_party/boringssl/crypto/bn/bn.c \
+    third_party/boringssl/crypto/bn/bn_asn1.c \
+    third_party/boringssl/crypto/bn/cmp.c \
+    third_party/boringssl/crypto/bn/convert.c \
+    third_party/boringssl/crypto/bn/ctx.c \
+    third_party/boringssl/crypto/bn/div.c \
+    third_party/boringssl/crypto/bn/exponentiation.c \
+    third_party/boringssl/crypto/bn/gcd.c \
+    third_party/boringssl/crypto/bn/generic.c \
+    third_party/boringssl/crypto/bn/kronecker.c \
+    third_party/boringssl/crypto/bn/montgomery.c \
+    third_party/boringssl/crypto/bn/mul.c \
+    third_party/boringssl/crypto/bn/prime.c \
+    third_party/boringssl/crypto/bn/random.c \
+    third_party/boringssl/crypto/bn/rsaz_exp.c \
+    third_party/boringssl/crypto/bn/shift.c \
+    third_party/boringssl/crypto/bn/sqrt.c \
+    third_party/boringssl/crypto/buf/buf.c \
+    third_party/boringssl/crypto/bytestring/ber.c \
+    third_party/boringssl/crypto/bytestring/cbb.c \
+    third_party/boringssl/crypto/bytestring/cbs.c \
+    third_party/boringssl/crypto/chacha/chacha_generic.c \
+    third_party/boringssl/crypto/chacha/chacha_vec.c \
+    third_party/boringssl/crypto/cipher/aead.c \
+    third_party/boringssl/crypto/cipher/cipher.c \
+    third_party/boringssl/crypto/cipher/derive_key.c \
+    third_party/boringssl/crypto/cipher/e_aes.c \
+    third_party/boringssl/crypto/cipher/e_chacha20poly1305.c \
+    third_party/boringssl/crypto/cipher/e_des.c \
+    third_party/boringssl/crypto/cipher/e_null.c \
+    third_party/boringssl/crypto/cipher/e_rc2.c \
+    third_party/boringssl/crypto/cipher/e_rc4.c \
+    third_party/boringssl/crypto/cipher/e_ssl3.c \
+    third_party/boringssl/crypto/cipher/e_tls.c \
+    third_party/boringssl/crypto/cipher/tls_cbc.c \
+    third_party/boringssl/crypto/cmac/cmac.c \
+    third_party/boringssl/crypto/conf/conf.c \
+    third_party/boringssl/crypto/cpu-arm.c \
+    third_party/boringssl/crypto/cpu-intel.c \
+    third_party/boringssl/crypto/crypto.c \
+    third_party/boringssl/crypto/curve25519/curve25519.c \
+    third_party/boringssl/crypto/des/des.c \
+    third_party/boringssl/crypto/dh/check.c \
+    third_party/boringssl/crypto/dh/dh.c \
+    third_party/boringssl/crypto/dh/dh_asn1.c \
+    third_party/boringssl/crypto/dh/params.c \
+    third_party/boringssl/crypto/digest/digest.c \
+    third_party/boringssl/crypto/digest/digests.c \
+    third_party/boringssl/crypto/directory_posix.c \
+    third_party/boringssl/crypto/directory_win.c \
+    third_party/boringssl/crypto/dsa/dsa.c \
+    third_party/boringssl/crypto/dsa/dsa_asn1.c \
+    third_party/boringssl/crypto/ec/ec.c \
+    third_party/boringssl/crypto/ec/ec_asn1.c \
+    third_party/boringssl/crypto/ec/ec_key.c \
+    third_party/boringssl/crypto/ec/ec_montgomery.c \
+    third_party/boringssl/crypto/ec/oct.c \
+    third_party/boringssl/crypto/ec/p224-64.c \
+    third_party/boringssl/crypto/ec/p256-64.c \
+    third_party/boringssl/crypto/ec/p256-x86_64.c \
+    third_party/boringssl/crypto/ec/simple.c \
+    third_party/boringssl/crypto/ec/util-64.c \
+    third_party/boringssl/crypto/ec/wnaf.c \
+    third_party/boringssl/crypto/ecdh/ecdh.c \
+    third_party/boringssl/crypto/ecdsa/ecdsa.c \
+    third_party/boringssl/crypto/ecdsa/ecdsa_asn1.c \
+    third_party/boringssl/crypto/engine/engine.c \
+    third_party/boringssl/crypto/err/err.c \
+    third_party/boringssl/crypto/evp/algorithm.c \
+    third_party/boringssl/crypto/evp/digestsign.c \
+    third_party/boringssl/crypto/evp/evp.c \
+    third_party/boringssl/crypto/evp/evp_asn1.c \
+    third_party/boringssl/crypto/evp/evp_ctx.c \
+    third_party/boringssl/crypto/evp/p_dsa_asn1.c \
+    third_party/boringssl/crypto/evp/p_ec.c \
+    third_party/boringssl/crypto/evp/p_ec_asn1.c \
+    third_party/boringssl/crypto/evp/p_rsa.c \
+    third_party/boringssl/crypto/evp/p_rsa_asn1.c \
+    third_party/boringssl/crypto/evp/pbkdf.c \
+    third_party/boringssl/crypto/evp/sign.c \
+    third_party/boringssl/crypto/ex_data.c \
+    third_party/boringssl/crypto/hkdf/hkdf.c \
+    third_party/boringssl/crypto/hmac/hmac.c \
+    third_party/boringssl/crypto/lhash/lhash.c \
+    third_party/boringssl/crypto/md4/md4.c \
+    third_party/boringssl/crypto/md5/md5.c \
+    third_party/boringssl/crypto/mem.c \
+    third_party/boringssl/crypto/modes/cbc.c \
+    third_party/boringssl/crypto/modes/cfb.c \
+    third_party/boringssl/crypto/modes/ctr.c \
+    third_party/boringssl/crypto/modes/gcm.c \
+    third_party/boringssl/crypto/modes/ofb.c \
+    third_party/boringssl/crypto/obj/obj.c \
+    third_party/boringssl/crypto/obj/obj_xref.c \
+    third_party/boringssl/crypto/pem/pem_all.c \
+    third_party/boringssl/crypto/pem/pem_info.c \
+    third_party/boringssl/crypto/pem/pem_lib.c \
+    third_party/boringssl/crypto/pem/pem_oth.c \
+    third_party/boringssl/crypto/pem/pem_pk8.c \
+    third_party/boringssl/crypto/pem/pem_pkey.c \
+    third_party/boringssl/crypto/pem/pem_x509.c \
+    third_party/boringssl/crypto/pem/pem_xaux.c \
+    third_party/boringssl/crypto/pkcs8/p5_pbe.c \
+    third_party/boringssl/crypto/pkcs8/p5_pbev2.c \
+    third_party/boringssl/crypto/pkcs8/p8_pkey.c \
+    third_party/boringssl/crypto/pkcs8/pkcs8.c \
+    third_party/boringssl/crypto/poly1305/poly1305.c \
+    third_party/boringssl/crypto/poly1305/poly1305_arm.c \
+    third_party/boringssl/crypto/poly1305/poly1305_vec.c \
+    third_party/boringssl/crypto/rand/rand.c \
+    third_party/boringssl/crypto/rand/urandom.c \
+    third_party/boringssl/crypto/rand/windows.c \
+    third_party/boringssl/crypto/rc4/rc4.c \
+    third_party/boringssl/crypto/refcount_c11.c \
+    third_party/boringssl/crypto/refcount_lock.c \
+    third_party/boringssl/crypto/rsa/blinding.c \
+    third_party/boringssl/crypto/rsa/padding.c \
+    third_party/boringssl/crypto/rsa/rsa.c \
+    third_party/boringssl/crypto/rsa/rsa_asn1.c \
+    third_party/boringssl/crypto/rsa/rsa_impl.c \
+    third_party/boringssl/crypto/sha/sha1.c \
+    third_party/boringssl/crypto/sha/sha256.c \
+    third_party/boringssl/crypto/sha/sha512.c \
+    third_party/boringssl/crypto/stack/stack.c \
+    third_party/boringssl/crypto/thread.c \
+    third_party/boringssl/crypto/thread_none.c \
+    third_party/boringssl/crypto/thread_pthread.c \
+    third_party/boringssl/crypto/thread_win.c \
+    third_party/boringssl/crypto/time_support.c \
+    third_party/boringssl/crypto/x509/a_digest.c \
+    third_party/boringssl/crypto/x509/a_sign.c \
+    third_party/boringssl/crypto/x509/a_strex.c \
+    third_party/boringssl/crypto/x509/a_verify.c \
+    third_party/boringssl/crypto/x509/asn1_gen.c \
+    third_party/boringssl/crypto/x509/by_dir.c \
+    third_party/boringssl/crypto/x509/by_file.c \
+    third_party/boringssl/crypto/x509/i2d_pr.c \
+    third_party/boringssl/crypto/x509/pkcs7.c \
+    third_party/boringssl/crypto/x509/t_crl.c \
+    third_party/boringssl/crypto/x509/t_req.c \
+    third_party/boringssl/crypto/x509/t_x509.c \
+    third_party/boringssl/crypto/x509/t_x509a.c \
+    third_party/boringssl/crypto/x509/x509.c \
+    third_party/boringssl/crypto/x509/x509_att.c \
+    third_party/boringssl/crypto/x509/x509_cmp.c \
+    third_party/boringssl/crypto/x509/x509_d2.c \
+    third_party/boringssl/crypto/x509/x509_def.c \
+    third_party/boringssl/crypto/x509/x509_ext.c \
+    third_party/boringssl/crypto/x509/x509_lu.c \
+    third_party/boringssl/crypto/x509/x509_obj.c \
+    third_party/boringssl/crypto/x509/x509_r2x.c \
+    third_party/boringssl/crypto/x509/x509_req.c \
+    third_party/boringssl/crypto/x509/x509_set.c \
+    third_party/boringssl/crypto/x509/x509_trs.c \
+    third_party/boringssl/crypto/x509/x509_txt.c \
+    third_party/boringssl/crypto/x509/x509_v3.c \
+    third_party/boringssl/crypto/x509/x509_vfy.c \
+    third_party/boringssl/crypto/x509/x509_vpm.c \
+    third_party/boringssl/crypto/x509/x509cset.c \
+    third_party/boringssl/crypto/x509/x509name.c \
+    third_party/boringssl/crypto/x509/x509rset.c \
+    third_party/boringssl/crypto/x509/x509spki.c \
+    third_party/boringssl/crypto/x509/x509type.c \
+    third_party/boringssl/crypto/x509/x_algor.c \
+    third_party/boringssl/crypto/x509/x_all.c \
+    third_party/boringssl/crypto/x509/x_attrib.c \
+    third_party/boringssl/crypto/x509/x_crl.c \
+    third_party/boringssl/crypto/x509/x_exten.c \
+    third_party/boringssl/crypto/x509/x_info.c \
+    third_party/boringssl/crypto/x509/x_name.c \
+    third_party/boringssl/crypto/x509/x_pkey.c \
+    third_party/boringssl/crypto/x509/x_pubkey.c \
+    third_party/boringssl/crypto/x509/x_req.c \
+    third_party/boringssl/crypto/x509/x_sig.c \
+    third_party/boringssl/crypto/x509/x_spki.c \
+    third_party/boringssl/crypto/x509/x_val.c \
+    third_party/boringssl/crypto/x509/x_x509.c \
+    third_party/boringssl/crypto/x509/x_x509a.c \
+    third_party/boringssl/crypto/x509v3/pcy_cache.c \
+    third_party/boringssl/crypto/x509v3/pcy_data.c \
+    third_party/boringssl/crypto/x509v3/pcy_lib.c \
+    third_party/boringssl/crypto/x509v3/pcy_map.c \
+    third_party/boringssl/crypto/x509v3/pcy_node.c \
+    third_party/boringssl/crypto/x509v3/pcy_tree.c \
+    third_party/boringssl/crypto/x509v3/v3_akey.c \
+    third_party/boringssl/crypto/x509v3/v3_akeya.c \
+    third_party/boringssl/crypto/x509v3/v3_alt.c \
+    third_party/boringssl/crypto/x509v3/v3_bcons.c \
+    third_party/boringssl/crypto/x509v3/v3_bitst.c \
+    third_party/boringssl/crypto/x509v3/v3_conf.c \
+    third_party/boringssl/crypto/x509v3/v3_cpols.c \
+    third_party/boringssl/crypto/x509v3/v3_crld.c \
+    third_party/boringssl/crypto/x509v3/v3_enum.c \
+    third_party/boringssl/crypto/x509v3/v3_extku.c \
+    third_party/boringssl/crypto/x509v3/v3_genn.c \
+    third_party/boringssl/crypto/x509v3/v3_ia5.c \
+    third_party/boringssl/crypto/x509v3/v3_info.c \
+    third_party/boringssl/crypto/x509v3/v3_int.c \
+    third_party/boringssl/crypto/x509v3/v3_lib.c \
+    third_party/boringssl/crypto/x509v3/v3_ncons.c \
+    third_party/boringssl/crypto/x509v3/v3_pci.c \
+    third_party/boringssl/crypto/x509v3/v3_pcia.c \
+    third_party/boringssl/crypto/x509v3/v3_pcons.c \
+    third_party/boringssl/crypto/x509v3/v3_pku.c \
+    third_party/boringssl/crypto/x509v3/v3_pmaps.c \
+    third_party/boringssl/crypto/x509v3/v3_prn.c \
+    third_party/boringssl/crypto/x509v3/v3_purp.c \
+    third_party/boringssl/crypto/x509v3/v3_skey.c \
+    third_party/boringssl/crypto/x509v3/v3_sxnet.c \
+    third_party/boringssl/crypto/x509v3/v3_utl.c \
+    third_party/boringssl/ssl/custom_extensions.c \
+    third_party/boringssl/ssl/d1_both.c \
+    third_party/boringssl/ssl/d1_clnt.c \
+    third_party/boringssl/ssl/d1_lib.c \
+    third_party/boringssl/ssl/d1_meth.c \
+    third_party/boringssl/ssl/d1_pkt.c \
+    third_party/boringssl/ssl/d1_srtp.c \
+    third_party/boringssl/ssl/d1_srvr.c \
+    third_party/boringssl/ssl/dtls_record.c \
+    third_party/boringssl/ssl/pqueue/pqueue.c \
+    third_party/boringssl/ssl/s3_both.c \
+    third_party/boringssl/ssl/s3_clnt.c \
+    third_party/boringssl/ssl/s3_enc.c \
+    third_party/boringssl/ssl/s3_lib.c \
+    third_party/boringssl/ssl/s3_meth.c \
+    third_party/boringssl/ssl/s3_pkt.c \
+    third_party/boringssl/ssl/s3_srvr.c \
+    third_party/boringssl/ssl/ssl_aead_ctx.c \
+    third_party/boringssl/ssl/ssl_asn1.c \
+    third_party/boringssl/ssl/ssl_buffer.c \
+    third_party/boringssl/ssl/ssl_cert.c \
+    third_party/boringssl/ssl/ssl_cipher.c \
+    third_party/boringssl/ssl/ssl_file.c \
+    third_party/boringssl/ssl/ssl_lib.c \
+    third_party/boringssl/ssl/ssl_rsa.c \
+    third_party/boringssl/ssl/ssl_session.c \
+    third_party/boringssl/ssl/ssl_stat.c \
+    third_party/boringssl/ssl/t1_enc.c \
+    third_party/boringssl/ssl/t1_lib.c \
+    third_party/boringssl/ssl/tls_record.c \
+    , $ext_shared, , -Wall -Werror \
+    -Wno-parentheses-equality -Wno-unused-value -std=c11 \
+    -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN \
+    -D_HAS_EXCEPTIONS=0 -DNOMINMAX)
+
+  PHP_ADD_BUILD_DIR($ext_builddir/src/php/ext/grpc)
+
+  PHP_ADD_BUILD_DIR($ext_builddir/src/boringssl)
+  PHP_ADD_BUILD_DIR($ext_builddir/src/core/census)
+  PHP_ADD_BUILD_DIR($ext_builddir/src/core/channel)
+  PHP_ADD_BUILD_DIR($ext_builddir/src/core/client_config)
+  PHP_ADD_BUILD_DIR($ext_builddir/src/core/client_config/lb_policies)
+  PHP_ADD_BUILD_DIR($ext_builddir/src/core/client_config/resolvers)
+  PHP_ADD_BUILD_DIR($ext_builddir/src/core/compression)
+  PHP_ADD_BUILD_DIR($ext_builddir/src/core/debug)
+  PHP_ADD_BUILD_DIR($ext_builddir/src/core/httpcli)
+  PHP_ADD_BUILD_DIR($ext_builddir/src/core/iomgr)
+  PHP_ADD_BUILD_DIR($ext_builddir/src/core/json)
+  PHP_ADD_BUILD_DIR($ext_builddir/src/core/profiling)
+  PHP_ADD_BUILD_DIR($ext_builddir/src/core/proto/grpc/lb/v0)
+  PHP_ADD_BUILD_DIR($ext_builddir/src/core/security)
+  PHP_ADD_BUILD_DIR($ext_builddir/src/core/support)
+  PHP_ADD_BUILD_DIR($ext_builddir/src/core/surface)
+  PHP_ADD_BUILD_DIR($ext_builddir/src/core/transport)
+  PHP_ADD_BUILD_DIR($ext_builddir/src/core/transport/chttp2)
+  PHP_ADD_BUILD_DIR($ext_builddir/src/core/tsi)
+  PHP_ADD_BUILD_DIR($ext_builddir/third_party/boringssl/crypto)
+  PHP_ADD_BUILD_DIR($ext_builddir/third_party/boringssl/crypto/aes)
+  PHP_ADD_BUILD_DIR($ext_builddir/third_party/boringssl/crypto/asn1)
+  PHP_ADD_BUILD_DIR($ext_builddir/third_party/boringssl/crypto/base64)
+  PHP_ADD_BUILD_DIR($ext_builddir/third_party/boringssl/crypto/bio)
+  PHP_ADD_BUILD_DIR($ext_builddir/third_party/boringssl/crypto/bn)
+  PHP_ADD_BUILD_DIR($ext_builddir/third_party/boringssl/crypto/bn/asm)
+  PHP_ADD_BUILD_DIR($ext_builddir/third_party/boringssl/crypto/buf)
+  PHP_ADD_BUILD_DIR($ext_builddir/third_party/boringssl/crypto/bytestring)
+  PHP_ADD_BUILD_DIR($ext_builddir/third_party/boringssl/crypto/chacha)
+  PHP_ADD_BUILD_DIR($ext_builddir/third_party/boringssl/crypto/cipher)
+  PHP_ADD_BUILD_DIR($ext_builddir/third_party/boringssl/crypto/cmac)
+  PHP_ADD_BUILD_DIR($ext_builddir/third_party/boringssl/crypto/conf)
+  PHP_ADD_BUILD_DIR($ext_builddir/third_party/boringssl/crypto/curve25519)
+  PHP_ADD_BUILD_DIR($ext_builddir/third_party/boringssl/crypto/des)
+  PHP_ADD_BUILD_DIR($ext_builddir/third_party/boringssl/crypto/dh)
+  PHP_ADD_BUILD_DIR($ext_builddir/third_party/boringssl/crypto/digest)
+  PHP_ADD_BUILD_DIR($ext_builddir/third_party/boringssl/crypto/dsa)
+  PHP_ADD_BUILD_DIR($ext_builddir/third_party/boringssl/crypto/ec)
+  PHP_ADD_BUILD_DIR($ext_builddir/third_party/boringssl/crypto/ecdh)
+  PHP_ADD_BUILD_DIR($ext_builddir/third_party/boringssl/crypto/ecdsa)
+  PHP_ADD_BUILD_DIR($ext_builddir/third_party/boringssl/crypto/engine)
+  PHP_ADD_BUILD_DIR($ext_builddir/third_party/boringssl/crypto/err)
+  PHP_ADD_BUILD_DIR($ext_builddir/third_party/boringssl/crypto/evp)
+  PHP_ADD_BUILD_DIR($ext_builddir/third_party/boringssl/crypto/hkdf)
+  PHP_ADD_BUILD_DIR($ext_builddir/third_party/boringssl/crypto/hmac)
+  PHP_ADD_BUILD_DIR($ext_builddir/third_party/boringssl/crypto/lhash)
+  PHP_ADD_BUILD_DIR($ext_builddir/third_party/boringssl/crypto/md4)
+  PHP_ADD_BUILD_DIR($ext_builddir/third_party/boringssl/crypto/md5)
+  PHP_ADD_BUILD_DIR($ext_builddir/third_party/boringssl/crypto/modes)
+  PHP_ADD_BUILD_DIR($ext_builddir/third_party/boringssl/crypto/obj)
+  PHP_ADD_BUILD_DIR($ext_builddir/third_party/boringssl/crypto/pem)
+  PHP_ADD_BUILD_DIR($ext_builddir/third_party/boringssl/crypto/pkcs8)
+  PHP_ADD_BUILD_DIR($ext_builddir/third_party/boringssl/crypto/poly1305)
+  PHP_ADD_BUILD_DIR($ext_builddir/third_party/boringssl/crypto/rand)
+  PHP_ADD_BUILD_DIR($ext_builddir/third_party/boringssl/crypto/rc4)
+  PHP_ADD_BUILD_DIR($ext_builddir/third_party/boringssl/crypto/rsa)
+  PHP_ADD_BUILD_DIR($ext_builddir/third_party/boringssl/crypto/sha)
+  PHP_ADD_BUILD_DIR($ext_builddir/third_party/boringssl/crypto/stack)
+  PHP_ADD_BUILD_DIR($ext_builddir/third_party/boringssl/crypto/x509)
+  PHP_ADD_BUILD_DIR($ext_builddir/third_party/boringssl/crypto/x509v3)
+  PHP_ADD_BUILD_DIR($ext_builddir/third_party/boringssl/ssl)
+  PHP_ADD_BUILD_DIR($ext_builddir/third_party/boringssl/ssl/pqueue)
+  PHP_ADD_BUILD_DIR($ext_builddir/third_party/nanopb)
+fi
diff --git a/doc/health-checking.md b/doc/health-checking.md
index 0b3f9c6..92512e9 100644
--- a/doc/health-checking.md
+++ b/doc/health-checking.md
@@ -26,7 +26,7 @@
 ```
 syntax = "proto3";
 
-package grpc.health.v1alpha;
+package grpc.health.v1;
 
 message HealthCheckRequest {
   string service = 1;
@@ -49,7 +49,7 @@
 A client can query the server’s health status by calling the `Check` method, and
 a deadline should be set on the rpc. The client can optionally set the service
 name it wants to query for health status. The suggested format of service name
-is `package_names.ServiceName`, such as `grpc.health.v1alpha.Health`.
+is `package_names.ServiceName`, such as `grpc.health.v1.Health`.
 
 The server should register all the services manually and set
 the individual status, including an empty service name and its status. For each
diff --git a/doc/load-balancing.md b/doc/load-balancing.md
new file mode 100644
index 0000000..681be02
--- /dev/null
+++ b/doc/load-balancing.md
@@ -0,0 +1,97 @@
+Load Balancing in gRPC
+=======================
+
+# Objective
+
+To design a load balancing API between a gRPC client and a Load Balancer to
+instruct the client how to send load to multiple backend servers. 
+
+# Background
+
+Prior to any gRPC specifics, we explore some usual ways to approach load
+balancing.
+
+### Proxy Model
+
+Using a proxy provides a solid trustable client that can report load to the load
+balancing system. Proxies typically require more resources to operate since they
+have temporary copies of the RPC request and response. This model also increases
+latency to the RPCs.
+
+The proxy model was deemed inefficient when considering request heavy services
+like storage. 
+
+### Balancing-aware Client
+
+This thicker client places more of the load balancing logic in the client. For
+example, the client could contain many load balancing policies (Round Robin,
+Random, etc) used to select servers from a list. In this model, a list of
+servers would be either statically configured in the client, provided by the
+name resolution system, an external load balancer, etc. In any case, the client
+is responsible for choosing the preferred server from the list. 
+
+One of the drawbacks of this approach is writing and maintaining the load
+balancing policies in multiple languages and/or versions of the clients. These
+policies can be fairly complicated. Some of the algorithms also require client
+to server communication so the client would need to get thicker to support
+additional RPCs to get health or load information in addition to sending RPCs
+for user requests.
+
+It would also significantly complicate the client's code: the new design hides
+the load balancing complexity of multiple layers and presents it as a simple
+list of servers to the client.
+
+### External Load Balancing Service
+
+The client load balancing code is kept simple and portable, implementing
+well-known algorithms (ie, Round Robin) for server selection.
+Complex load balancing algorithms are instead provided by the load balancer. The
+client relies on the load balancer to provide _load balancing configuration_ and
+_the list of servers_ to which the client should send requests. The balancer
+updates the server list as needed to balance the load as well as handle server
+unavailability or health issues. The load balancer will make any necessary
+complex decisions and inform the client. The load balancer may communicate with
+the backend servers to collect load and health information.
+
+# Proposed Architecture
+
+The gRPC load balancing approach follows the third approach, by having an
+external load balancer which provides simple clients with a list of servers.
+
+## Client
+
+When establishing a gRPC stream to the balancer, the client will send an initial
+request to the load balancer (via a regular gRPC message). The load balancer
+will respond with client config (including, for example, settings for flow
+control, RPC deadlines, etc.) or a redirect to another load balancer. If the
+balancer did not redirect the client, it will then send a list of servers to the
+client. The client will contain simple load balancing logic for choosing the
+next server when it needs to send a request.
+
+## Load Balancer
+
+The Load Balancer is responsible for providing the client with a list of servers
+and client RPC parameters. The balancer chooses when to update the list of
+servers and can decide whether to provide a complete list, a subset, or a
+specific list of “picked” servers in a particular order. The balancer can
+optionally provide an expiration interval after which the server list should no
+longer be trusted and should be updated by the balancer.
+
+The load balancer may open reporting streams to each server contained in the
+server list. These streams are primarily used for load reporting. For example,
+Weighted Round Robin requires that the servers report utilization to the load
+balancer in order to compute the next list of servers.
+
+## Server
+
+The gRPC Server is responsible for answering RPC requests and providing
+responses to the client. The server will also report load to the load balancer
+if a reporting stream was opened for this purpose.
+
+### Security 
+
+The load balancer may be separate from the actual server backends and a
+compromise of the load balancer should only lead to a compromise of the
+loadbalancing functionality. In other words, a compromised load balancer should
+not be able to cause a client to trust a (potentially malicious) backend server
+any more than in a comparable situation without loadbalancing. 
diff --git a/examples/csharp/helloworld/.nuget/packages.config b/examples/csharp/helloworld/.nuget/packages.config
index 1cbe7e1..fb77831 100644
--- a/examples/csharp/helloworld/.nuget/packages.config
+++ b/examples/csharp/helloworld/.nuget/packages.config
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
 <packages>
-  <package id="Grpc.Tools" version="0.12.0" />
+  <package id="Grpc.Tools" version="0.13.0" />
 </packages>
\ No newline at end of file
diff --git a/examples/csharp/helloworld/Greeter/Greeter.csproj b/examples/csharp/helloworld/Greeter/Greeter.csproj
index fa1c20f..a25ad5f 100644
--- a/examples/csharp/helloworld/Greeter/Greeter.csproj
+++ b/examples/csharp/helloworld/Greeter/Greeter.csproj
@@ -10,7 +10,7 @@
     <RootNamespace>Greeter</RootNamespace>
     <AssemblyName>Greeter</AssemblyName>
     <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
-    <NuGetPackageImportStamp>4eea1d1c</NuGetPackageImportStamp>
+    <NuGetPackageImportStamp>39f4a691</NuGetPackageImportStamp>
   </PropertyGroup>
   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
     <DebugSymbols>true</DebugSymbols>
@@ -31,15 +31,18 @@
     <ConsolePause>false</ConsolePause>
   </PropertyGroup>
   <ItemGroup>
-    <Reference Include="Google.Protobuf">
-      <HintPath>..\packages\Google.Protobuf.3.0.0-alpha4\lib\portable-net45+netcore45+wpa81+wp8\Google.Protobuf.dll</HintPath>
+    <Reference Include="Google.Protobuf, Version=3.0.0.0, Culture=neutral, PublicKeyToken=a7d26565bac4d604, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\packages\Google.Protobuf.3.0.0-beta2\lib\portable-net45+netcore45+wpa81+wp8\Google.Protobuf.dll</HintPath>
     </Reference>
-    <Reference Include="Grpc.Core">
-      <HintPath>..\packages\Grpc.Core.0.12.0\lib\net45\Grpc.Core.dll</HintPath>
+    <Reference Include="Grpc.Core, Version=0.13.0.0, Culture=neutral, PublicKeyToken=d754f35622e28bad, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\packages\Grpc.Core.0.13.0\lib\net45\Grpc.Core.dll</HintPath>
     </Reference>
     <Reference Include="System" />
-    <Reference Include="System.Interactive.Async">
-      <HintPath>..\packages\Ix-Async.1.2.3\lib\net45\System.Interactive.Async.dll</HintPath>
+    <Reference Include="System.Interactive.Async, Version=1.2.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\packages\Ix-Async.1.2.5\lib\net45\System.Interactive.Async.dll</HintPath>
     </Reference>
   </ItemGroup>
   <ItemGroup>
@@ -53,15 +56,11 @@
     <None Include="protos\helloworld.proto" />
   </ItemGroup>
   <ItemGroup />
-  <Import Project="..\packages\grpc.dependencies.zlib.redist.1.2.8.10\build\portable-net45+netcore45+wpa81+wp8\grpc.dependencies.zlib.redist.targets" Condition="Exists('..\packages\grpc.dependencies.zlib.redist.1.2.8.10\build\portable-net45+netcore45+wpa81+wp8\grpc.dependencies.zlib.redist.targets')" />
+  <Import Project="..\packages\grpc.native.csharp.0.13.0\build\portable-net45+netcore45+wpa81+wp8\grpc.native.csharp.targets" Condition="Exists('..\packages\grpc.native.csharp.0.13.0\build\portable-net45+netcore45+wpa81+wp8\grpc.native.csharp.targets')" />
   <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
     <PropertyGroup>
       <ErrorText>This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them.  For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
     </PropertyGroup>
-    <Error Condition="!Exists('..\packages\grpc.dependencies.zlib.redist.1.2.8.10\build\portable-net45+netcore45+wpa81+wp8\grpc.dependencies.zlib.redist.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\grpc.dependencies.zlib.redist.1.2.8.10\build\portable-net45+netcore45+wpa81+wp8\grpc.dependencies.zlib.redist.targets'))" />
-    <Error Condition="!Exists('..\packages\grpc.dependencies.openssl.redist.1.0.204.1\build\portable-net45+netcore45+wpa81+wp8\grpc.dependencies.openssl.redist.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\grpc.dependencies.openssl.redist.1.0.204.1\build\portable-net45+netcore45+wpa81+wp8\grpc.dependencies.openssl.redist.targets'))" />
-    <Error Condition="!Exists('..\packages\grpc.native.csharp.0.12.0\build\portable-net45+netcore45+wpa81+wp8\grpc.native.csharp.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\grpc.native.csharp.0.12.0\build\portable-net45+netcore45+wpa81+wp8\grpc.native.csharp.targets'))" />
+    <Error Condition="!Exists('..\packages\grpc.native.csharp.0.13.0\build\portable-net45+netcore45+wpa81+wp8\grpc.native.csharp.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\grpc.native.csharp.0.13.0\build\portable-net45+netcore45+wpa81+wp8\grpc.native.csharp.targets'))" />
   </Target>
-  <Import Project="..\packages\grpc.dependencies.openssl.redist.1.0.204.1\build\portable-net45+netcore45+wpa81+wp8\grpc.dependencies.openssl.redist.targets" Condition="Exists('..\packages\grpc.dependencies.openssl.redist.1.0.204.1\build\portable-net45+netcore45+wpa81+wp8\grpc.dependencies.openssl.redist.targets')" />
-  <Import Project="..\packages\grpc.native.csharp.0.12.0\build\portable-net45+netcore45+wpa81+wp8\grpc.native.csharp.targets" Condition="Exists('..\packages\grpc.native.csharp.0.12.0\build\portable-net45+netcore45+wpa81+wp8\grpc.native.csharp.targets')" />
 </Project>
\ No newline at end of file
diff --git a/examples/csharp/helloworld/Greeter/Helloworld.cs b/examples/csharp/helloworld/Greeter/Helloworld.cs
index 668165a..63969b7 100644
--- a/examples/csharp/helloworld/Greeter/Helloworld.cs
+++ b/examples/csharp/helloworld/Greeter/Helloworld.cs
@@ -9,41 +9,46 @@
 using scg = global::System.Collections.Generic;
 namespace Helloworld {
 
+  /// <summary>Holder for reflection information generated from helloworld.proto</summary>
   [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
-  public static partial class Helloworld {
+  public static partial class HelloworldReflection {
 
     #region Descriptor
+    /// <summary>File descriptor for helloworld.proto</summary>
     public static pbr::FileDescriptor Descriptor {
       get { return descriptor; }
     }
     private static pbr::FileDescriptor descriptor;
 
-    static Helloworld() {
+    static HelloworldReflection() {
       byte[] descriptorData = global::System.Convert.FromBase64String(
           string.Concat(
-            "ChBoZWxsb3dvcmxkLnByb3RvEgpoZWxsb3dvcmxkIhwKDEhlbGxvUmVxdWVz", 
-            "dBIMCgRuYW1lGAEgASgJIh0KCkhlbGxvUmVwbHkSDwoHbWVzc2FnZRgBIAEo", 
-            "CTJJCgdHcmVldGVyEj4KCFNheUhlbGxvEhguaGVsbG93b3JsZC5IZWxsb1Jl", 
-            "cXVlc3QaFi5oZWxsb3dvcmxkLkhlbGxvUmVwbHkiAEIYChBpby5ncnBjLmV4", 
+            "ChBoZWxsb3dvcmxkLnByb3RvEgpoZWxsb3dvcmxkIhwKDEhlbGxvUmVxdWVz",
+            "dBIMCgRuYW1lGAEgASgJIh0KCkhlbGxvUmVwbHkSDwoHbWVzc2FnZRgBIAEo",
+            "CTJJCgdHcmVldGVyEj4KCFNheUhlbGxvEhguaGVsbG93b3JsZC5IZWxsb1Jl",
+            "cXVlc3QaFi5oZWxsb3dvcmxkLkhlbGxvUmVwbHkiAEIYChBpby5ncnBjLmV4",
             "YW1wbGVzogIDSExXYgZwcm90bzM="));
-      descriptor = pbr::FileDescriptor.InternalBuildGeneratedFileFrom(descriptorData,
+      descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
           new pbr::FileDescriptor[] { },
           new pbr::GeneratedCodeInfo(null, new pbr::GeneratedCodeInfo[] {
-            new pbr::GeneratedCodeInfo(typeof(global::Helloworld.HelloRequest), new[]{ "Name" }, null, null, null),
-            new pbr::GeneratedCodeInfo(typeof(global::Helloworld.HelloReply), new[]{ "Message" }, null, null, null)
+            new pbr::GeneratedCodeInfo(typeof(global::Helloworld.HelloRequest), global::Helloworld.HelloRequest.Parser, new[]{ "Name" }, null, null, null),
+            new pbr::GeneratedCodeInfo(typeof(global::Helloworld.HelloReply), global::Helloworld.HelloReply.Parser, new[]{ "Message" }, null, null, null)
           }));
     }
     #endregion
 
   }
   #region Messages
+  /// <summary>
+  ///  The request message containing the user's name.
+  /// </summary>
   [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
   public sealed partial class HelloRequest : pb::IMessage<HelloRequest> {
     private static readonly pb::MessageParser<HelloRequest> _parser = new pb::MessageParser<HelloRequest>(() => new HelloRequest());
     public static pb::MessageParser<HelloRequest> Parser { get { return _parser; } }
 
     public static pbr::MessageDescriptor Descriptor {
-      get { return global::Helloworld.Helloworld.Descriptor.MessageTypes[0]; }
+      get { return global::Helloworld.HelloworldReflection.Descriptor.MessageTypes[0]; }
     }
 
     pbr::MessageDescriptor pb::IMessage.Descriptor {
@@ -64,6 +69,7 @@
       return new HelloRequest(this);
     }
 
+    /// <summary>Field number for the "name" field.</summary>
     public const int NameFieldNumber = 1;
     private string name_ = "";
     public string Name {
@@ -95,7 +101,7 @@
     }
 
     public override string ToString() {
-      return pb::JsonFormatter.Default.Format(this);
+      return pb::JsonFormatter.ToDiagnosticString(this);
     }
 
     public void WriteTo(pb::CodedOutputStream output) {
@@ -139,13 +145,16 @@
 
   }
 
+  /// <summary>
+  ///  The response message containing the greetings
+  /// </summary>
   [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
   public sealed partial class HelloReply : pb::IMessage<HelloReply> {
     private static readonly pb::MessageParser<HelloReply> _parser = new pb::MessageParser<HelloReply>(() => new HelloReply());
     public static pb::MessageParser<HelloReply> Parser { get { return _parser; } }
 
     public static pbr::MessageDescriptor Descriptor {
-      get { return global::Helloworld.Helloworld.Descriptor.MessageTypes[1]; }
+      get { return global::Helloworld.HelloworldReflection.Descriptor.MessageTypes[1]; }
     }
 
     pbr::MessageDescriptor pb::IMessage.Descriptor {
@@ -166,6 +175,7 @@
       return new HelloReply(this);
     }
 
+    /// <summary>Field number for the "message" field.</summary>
     public const int MessageFieldNumber = 1;
     private string message_ = "";
     public string Message {
@@ -197,7 +207,7 @@
     }
 
     public override string ToString() {
-      return pb::JsonFormatter.Default.Format(this);
+      return pb::JsonFormatter.ToDiagnosticString(this);
     }
 
     public void WriteTo(pb::CodedOutputStream output) {
diff --git a/examples/csharp/helloworld/Greeter/HelloworldGrpc.cs b/examples/csharp/helloworld/Greeter/HelloworldGrpc.cs
index edfe4d2..4014bc2 100644
--- a/examples/csharp/helloworld/Greeter/HelloworldGrpc.cs
+++ b/examples/csharp/helloworld/Greeter/HelloworldGrpc.cs
@@ -25,7 +25,7 @@
     // service descriptor
     public static global::Google.Protobuf.Reflection.ServiceDescriptor Descriptor
     {
-      get { return global::Helloworld.Helloworld.Descriptor.Services[0]; }
+      get { return global::Helloworld.HelloworldReflection.Descriptor.Services[0]; }
     }
 
     // client interface
diff --git a/examples/csharp/helloworld/Greeter/packages.config b/examples/csharp/helloworld/Greeter/packages.config
index cabcadc..abe9ad0 100644
--- a/examples/csharp/helloworld/Greeter/packages.config
+++ b/examples/csharp/helloworld/Greeter/packages.config
@@ -1,10 +1,8 @@
 <?xml version="1.0" encoding="utf-8"?>
 <packages>
-  <package id="Google.Protobuf" version="3.0.0-alpha4" targetFramework="net45" />
-  <package id="Grpc" version="0.12.0" targetFramework="net45" />
-  <package id="Grpc.Core" version="0.12.0" targetFramework="net45" />
-  <package id="grpc.dependencies.openssl.redist" version="1.0.204.1" targetFramework="net45" />
-  <package id="grpc.dependencies.zlib.redist" version="1.2.8.10" targetFramework="net45" />
-  <package id="grpc.native.csharp" version="0.12.0" targetFramework="net45" />
-  <package id="Ix-Async" version="1.2.3" targetFramework="net45" />
+  <package id="Google.Protobuf" version="3.0.0-beta2" targetFramework="net45" />
+  <package id="Grpc" version="0.13.0" targetFramework="net45" />
+  <package id="Grpc.Core" version="0.13.0" targetFramework="net45" />
+  <package id="grpc.native.csharp" version="0.13.0" targetFramework="net45" />
+  <package id="Ix-Async" version="1.2.5" targetFramework="net45" />
 </packages>
\ No newline at end of file
diff --git a/examples/csharp/helloworld/GreeterClient/GreeterClient.csproj b/examples/csharp/helloworld/GreeterClient/GreeterClient.csproj
index 164a616..a71cfee 100644
--- a/examples/csharp/helloworld/GreeterClient/GreeterClient.csproj
+++ b/examples/csharp/helloworld/GreeterClient/GreeterClient.csproj
@@ -10,7 +10,7 @@
     <RootNamespace>GreeterClient</RootNamespace>
     <AssemblyName>GreeterClient</AssemblyName>
     <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
-    <NuGetPackageImportStamp>29206d49</NuGetPackageImportStamp>
+    <NuGetPackageImportStamp>dcebbc77</NuGetPackageImportStamp>
   </PropertyGroup>
   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
     <DebugSymbols>true</DebugSymbols>
@@ -31,15 +31,18 @@
     <Externalconsole>true</Externalconsole>
   </PropertyGroup>
   <ItemGroup>
-    <Reference Include="Google.Protobuf">
-      <HintPath>..\packages\Google.Protobuf.3.0.0-alpha4\lib\portable-net45+netcore45+wpa81+wp8\Google.Protobuf.dll</HintPath>
+    <Reference Include="Google.Protobuf, Version=3.0.0.0, Culture=neutral, PublicKeyToken=a7d26565bac4d604, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\packages\Google.Protobuf.3.0.0-beta2\lib\portable-net45+netcore45+wpa81+wp8\Google.Protobuf.dll</HintPath>
     </Reference>
-    <Reference Include="Grpc.Core">
-      <HintPath>..\packages\Grpc.Core.0.12.0\lib\net45\Grpc.Core.dll</HintPath>
+    <Reference Include="Grpc.Core, Version=0.13.0.0, Culture=neutral, PublicKeyToken=d754f35622e28bad, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\packages\Grpc.Core.0.13.0\lib\net45\Grpc.Core.dll</HintPath>
     </Reference>
     <Reference Include="System" />
-    <Reference Include="System.Interactive.Async">
-      <HintPath>..\packages\Ix-Async.1.2.3\lib\net45\System.Interactive.Async.dll</HintPath>
+    <Reference Include="System.Interactive.Async, Version=1.2.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\packages\Ix-Async.1.2.5\lib\net45\System.Interactive.Async.dll</HintPath>
     </Reference>
   </ItemGroup>
   <ItemGroup>
@@ -56,15 +59,11 @@
   <ItemGroup>
     <None Include="packages.config" />
   </ItemGroup>
-  <Import Project="..\packages\grpc.dependencies.zlib.redist.1.2.8.10\build\portable-net45+netcore45+wpa81+wp8\grpc.dependencies.zlib.redist.targets" Condition="Exists('..\packages\grpc.dependencies.zlib.redist.1.2.8.10\build\portable-net45+netcore45+wpa81+wp8\grpc.dependencies.zlib.redist.targets')" />
+  <Import Project="..\packages\grpc.native.csharp.0.13.0\build\portable-net45+netcore45+wpa81+wp8\grpc.native.csharp.targets" Condition="Exists('..\packages\grpc.native.csharp.0.13.0\build\portable-net45+netcore45+wpa81+wp8\grpc.native.csharp.targets')" />
   <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
     <PropertyGroup>
       <ErrorText>This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them.  For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
     </PropertyGroup>
-    <Error Condition="!Exists('..\packages\grpc.dependencies.zlib.redist.1.2.8.10\build\portable-net45+netcore45+wpa81+wp8\grpc.dependencies.zlib.redist.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\grpc.dependencies.zlib.redist.1.2.8.10\build\portable-net45+netcore45+wpa81+wp8\grpc.dependencies.zlib.redist.targets'))" />
-    <Error Condition="!Exists('..\packages\grpc.dependencies.openssl.redist.1.0.204.1\build\portable-net45+netcore45+wpa81+wp8\grpc.dependencies.openssl.redist.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\grpc.dependencies.openssl.redist.1.0.204.1\build\portable-net45+netcore45+wpa81+wp8\grpc.dependencies.openssl.redist.targets'))" />
-    <Error Condition="!Exists('..\packages\grpc.native.csharp.0.12.0\build\portable-net45+netcore45+wpa81+wp8\grpc.native.csharp.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\grpc.native.csharp.0.12.0\build\portable-net45+netcore45+wpa81+wp8\grpc.native.csharp.targets'))" />
+    <Error Condition="!Exists('..\packages\grpc.native.csharp.0.13.0\build\portable-net45+netcore45+wpa81+wp8\grpc.native.csharp.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\grpc.native.csharp.0.13.0\build\portable-net45+netcore45+wpa81+wp8\grpc.native.csharp.targets'))" />
   </Target>
-  <Import Project="..\packages\grpc.dependencies.openssl.redist.1.0.204.1\build\portable-net45+netcore45+wpa81+wp8\grpc.dependencies.openssl.redist.targets" Condition="Exists('..\packages\grpc.dependencies.openssl.redist.1.0.204.1\build\portable-net45+netcore45+wpa81+wp8\grpc.dependencies.openssl.redist.targets')" />
-  <Import Project="..\packages\grpc.native.csharp.0.12.0\build\portable-net45+netcore45+wpa81+wp8\grpc.native.csharp.targets" Condition="Exists('..\packages\grpc.native.csharp.0.12.0\build\portable-net45+netcore45+wpa81+wp8\grpc.native.csharp.targets')" />
 </Project>
\ No newline at end of file
diff --git a/examples/csharp/helloworld/GreeterClient/packages.config b/examples/csharp/helloworld/GreeterClient/packages.config
index cabcadc..abe9ad0 100644
--- a/examples/csharp/helloworld/GreeterClient/packages.config
+++ b/examples/csharp/helloworld/GreeterClient/packages.config
@@ -1,10 +1,8 @@
 <?xml version="1.0" encoding="utf-8"?>
 <packages>
-  <package id="Google.Protobuf" version="3.0.0-alpha4" targetFramework="net45" />
-  <package id="Grpc" version="0.12.0" targetFramework="net45" />
-  <package id="Grpc.Core" version="0.12.0" targetFramework="net45" />
-  <package id="grpc.dependencies.openssl.redist" version="1.0.204.1" targetFramework="net45" />
-  <package id="grpc.dependencies.zlib.redist" version="1.2.8.10" targetFramework="net45" />
-  <package id="grpc.native.csharp" version="0.12.0" targetFramework="net45" />
-  <package id="Ix-Async" version="1.2.3" targetFramework="net45" />
+  <package id="Google.Protobuf" version="3.0.0-beta2" targetFramework="net45" />
+  <package id="Grpc" version="0.13.0" targetFramework="net45" />
+  <package id="Grpc.Core" version="0.13.0" targetFramework="net45" />
+  <package id="grpc.native.csharp" version="0.13.0" targetFramework="net45" />
+  <package id="Ix-Async" version="1.2.5" targetFramework="net45" />
 </packages>
\ No newline at end of file
diff --git a/examples/csharp/helloworld/GreeterServer/GreeterServer.csproj b/examples/csharp/helloworld/GreeterServer/GreeterServer.csproj
index 56436d3..34eea8c 100644
--- a/examples/csharp/helloworld/GreeterServer/GreeterServer.csproj
+++ b/examples/csharp/helloworld/GreeterServer/GreeterServer.csproj
@@ -10,7 +10,7 @@
     <RootNamespace>GreeterServer</RootNamespace>
     <AssemblyName>GreeterServer</AssemblyName>
     <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
-    <NuGetPackageImportStamp>8a2cae0f</NuGetPackageImportStamp>
+    <NuGetPackageImportStamp>2ea5dfd0</NuGetPackageImportStamp>
   </PropertyGroup>
   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
     <DebugSymbols>true</DebugSymbols>
@@ -31,15 +31,18 @@
     <Externalconsole>true</Externalconsole>
   </PropertyGroup>
   <ItemGroup>
-    <Reference Include="Google.Protobuf">
-      <HintPath>..\packages\Google.Protobuf.3.0.0-alpha4\lib\portable-net45+netcore45+wpa81+wp8\Google.Protobuf.dll</HintPath>
+    <Reference Include="Google.Protobuf, Version=3.0.0.0, Culture=neutral, PublicKeyToken=a7d26565bac4d604, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\packages\Google.Protobuf.3.0.0-beta2\lib\portable-net45+netcore45+wpa81+wp8\Google.Protobuf.dll</HintPath>
     </Reference>
-    <Reference Include="Grpc.Core">
-      <HintPath>..\packages\Grpc.Core.0.12.0\lib\net45\Grpc.Core.dll</HintPath>
+    <Reference Include="Grpc.Core, Version=0.13.0.0, Culture=neutral, PublicKeyToken=d754f35622e28bad, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\packages\Grpc.Core.0.13.0\lib\net45\Grpc.Core.dll</HintPath>
     </Reference>
     <Reference Include="System" />
-    <Reference Include="System.Interactive.Async">
-      <HintPath>..\packages\Ix-Async.1.2.3\lib\net45\System.Interactive.Async.dll</HintPath>
+    <Reference Include="System.Interactive.Async, Version=1.2.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\packages\Ix-Async.1.2.5\lib\net45\System.Interactive.Async.dll</HintPath>
     </Reference>
   </ItemGroup>
   <ItemGroup>
@@ -56,15 +59,11 @@
   <ItemGroup>
     <None Include="packages.config" />
   </ItemGroup>
-  <Import Project="..\packages\grpc.dependencies.zlib.redist.1.2.8.10\build\portable-net45+netcore45+wpa81+wp8\grpc.dependencies.zlib.redist.targets" Condition="Exists('..\packages\grpc.dependencies.zlib.redist.1.2.8.10\build\portable-net45+netcore45+wpa81+wp8\grpc.dependencies.zlib.redist.targets')" />
+  <Import Project="..\packages\grpc.native.csharp.0.13.0\build\portable-net45+netcore45+wpa81+wp8\grpc.native.csharp.targets" Condition="Exists('..\packages\grpc.native.csharp.0.13.0\build\portable-net45+netcore45+wpa81+wp8\grpc.native.csharp.targets')" />
   <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
     <PropertyGroup>
       <ErrorText>This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them.  For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
     </PropertyGroup>
-    <Error Condition="!Exists('..\packages\grpc.dependencies.zlib.redist.1.2.8.10\build\portable-net45+netcore45+wpa81+wp8\grpc.dependencies.zlib.redist.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\grpc.dependencies.zlib.redist.1.2.8.10\build\portable-net45+netcore45+wpa81+wp8\grpc.dependencies.zlib.redist.targets'))" />
-    <Error Condition="!Exists('..\packages\grpc.dependencies.openssl.redist.1.0.204.1\build\portable-net45+netcore45+wpa81+wp8\grpc.dependencies.openssl.redist.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\grpc.dependencies.openssl.redist.1.0.204.1\build\portable-net45+netcore45+wpa81+wp8\grpc.dependencies.openssl.redist.targets'))" />
-    <Error Condition="!Exists('..\packages\grpc.native.csharp.0.12.0\build\portable-net45+netcore45+wpa81+wp8\grpc.native.csharp.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\grpc.native.csharp.0.12.0\build\portable-net45+netcore45+wpa81+wp8\grpc.native.csharp.targets'))" />
+    <Error Condition="!Exists('..\packages\grpc.native.csharp.0.13.0\build\portable-net45+netcore45+wpa81+wp8\grpc.native.csharp.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\grpc.native.csharp.0.13.0\build\portable-net45+netcore45+wpa81+wp8\grpc.native.csharp.targets'))" />
   </Target>
-  <Import Project="..\packages\grpc.dependencies.openssl.redist.1.0.204.1\build\portable-net45+netcore45+wpa81+wp8\grpc.dependencies.openssl.redist.targets" Condition="Exists('..\packages\grpc.dependencies.openssl.redist.1.0.204.1\build\portable-net45+netcore45+wpa81+wp8\grpc.dependencies.openssl.redist.targets')" />
-  <Import Project="..\packages\grpc.native.csharp.0.12.0\build\portable-net45+netcore45+wpa81+wp8\grpc.native.csharp.targets" Condition="Exists('..\packages\grpc.native.csharp.0.12.0\build\portable-net45+netcore45+wpa81+wp8\grpc.native.csharp.targets')" />
 </Project>
\ No newline at end of file
diff --git a/examples/csharp/helloworld/GreeterServer/packages.config b/examples/csharp/helloworld/GreeterServer/packages.config
index cabcadc..abe9ad0 100644
--- a/examples/csharp/helloworld/GreeterServer/packages.config
+++ b/examples/csharp/helloworld/GreeterServer/packages.config
@@ -1,10 +1,8 @@
 <?xml version="1.0" encoding="utf-8"?>
 <packages>
-  <package id="Google.Protobuf" version="3.0.0-alpha4" targetFramework="net45" />
-  <package id="Grpc" version="0.12.0" targetFramework="net45" />
-  <package id="Grpc.Core" version="0.12.0" targetFramework="net45" />
-  <package id="grpc.dependencies.openssl.redist" version="1.0.204.1" targetFramework="net45" />
-  <package id="grpc.dependencies.zlib.redist" version="1.2.8.10" targetFramework="net45" />
-  <package id="grpc.native.csharp" version="0.12.0" targetFramework="net45" />
-  <package id="Ix-Async" version="1.2.3" targetFramework="net45" />
+  <package id="Google.Protobuf" version="3.0.0-beta2" targetFramework="net45" />
+  <package id="Grpc" version="0.13.0" targetFramework="net45" />
+  <package id="Grpc.Core" version="0.13.0" targetFramework="net45" />
+  <package id="grpc.native.csharp" version="0.13.0" targetFramework="net45" />
+  <package id="Ix-Async" version="1.2.5" targetFramework="net45" />
 </packages>
\ No newline at end of file
diff --git a/examples/csharp/helloworld/README.md b/examples/csharp/helloworld/README.md
index f1af1f6..63131ed 100644
--- a/examples/csharp/helloworld/README.md
+++ b/examples/csharp/helloworld/README.md
@@ -16,35 +16,17 @@
 - Visual Studio 2013 or 2015
 
 **Linux**
-- Mono
-- Monodevelop 5.9 with NuGet Add-in installed
+- Mono 4.0+
+- Monodevelop 5.9+ (with NuGet plugin installed)
 
 **Mac OS X**
-- Xamarin Studio (with NuGet plugin installed)
+- Xamarin Studio 5.9+
 - [homebrew][]
 
 BUILD
 -------
 
-**Windows**
-
-- Open solution `Greeter.sln` with Visual Studio
-
-- Build the solution (this will automatically download NuGet dependencies)
-
-**Linux (Debian)**
-
-- Install gRPC C core and C# native extension using [How to use gRPC C#][] instructions
-
-- Open solution `Greeter.sln` in MonoDevelop.
-
-- Build the solution (you need to manually restore dependencies by using `mono nuget.exe restore` if you don't have NuGet add-in)
-
-**Mac OS X**
-
-- Install gRPC C core and C# native extension using [How to use gRPC C#][] instructions
-
-- Open solution `Greeter.sln` with Xamarin Studio
+- Open solution `Greeter.sln` with Visual Studio, Monodevelop (on Linux) or Xamarin Studio (on Mac OS X)
 
 - Build the solution (this will automatically download NuGet dependencies)
 
@@ -65,7 +47,7 @@
   > GreeterClient.exe
   ```
 
-You can also run the server and client directly from Visual Studio.
+You can also run the server and client directly from the IDE.
 
 On Linux or Mac, use `mono GreeterServer.exe` and `mono GreeterClient.exe` to run the server and client.
 
@@ -76,5 +58,4 @@
 
 [homebrew]:http://brew.sh
 [helloworld.proto]:../../protos/helloworld.proto
-[How to use gRPC C#]:../../../src/csharp#how-to-use
 [gRPC Basics: C#]:http://www.grpc.io/docs/tutorials/basic/csharp.html
diff --git a/examples/csharp/helloworld/generate_protos.bat b/examples/csharp/helloworld/generate_protos.bat
index 8ba2c2e..7f3654c 100644
--- a/examples/csharp/helloworld/generate_protos.bat
+++ b/examples/csharp/helloworld/generate_protos.bat
@@ -5,6 +5,6 @@
 @rem enter this directory
 cd /d %~dp0
 
-packages\Google.Protobuf.3.0.0-alpha4\tools\protoc.exe -I../../protos --csharp_out Greeter  ../../protos/helloworld.proto --grpc_out Greeter --plugin=protoc-gen-grpc=packages\Grpc.Tools.0.12.0\tools\grpc_csharp_plugin.exe
+packages\Google.Protobuf.3.0.0-beta2\tools\protoc.exe -I../../protos --csharp_out Greeter  ../../protos/helloworld.proto --grpc_out Greeter --plugin=protoc-gen-grpc=packages\Grpc.Tools.0.13.0\tools\grpc_csharp_plugin.exe
 
 endlocal
\ No newline at end of file
diff --git a/examples/csharp/route_guide/.nuget/packages.config b/examples/csharp/route_guide/.nuget/packages.config
index 1cbe7e1..fb77831 100644
--- a/examples/csharp/route_guide/.nuget/packages.config
+++ b/examples/csharp/route_guide/.nuget/packages.config
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
 <packages>
-  <package id="Grpc.Tools" version="0.12.0" />
+  <package id="Grpc.Tools" version="0.13.0" />
 </packages>
\ No newline at end of file
diff --git a/examples/csharp/route_guide/RouteGuide/RouteGuide.cs b/examples/csharp/route_guide/RouteGuide/RouteGuide.cs
index deb97e1..3bd79df 100644
--- a/examples/csharp/route_guide/RouteGuide/RouteGuide.cs
+++ b/examples/csharp/route_guide/RouteGuide/RouteGuide.cs
@@ -9,57 +9,62 @@
 using scg = global::System.Collections.Generic;
 namespace Routeguide {
 
-  namespace Proto {
+  /// <summary>Holder for reflection information generated from route_guide.proto</summary>
+  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+  public static partial class RouteGuideReflection {
 
-    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
-    public static partial class RouteGuide {
-
-      #region Descriptor
-      public static pbr::FileDescriptor Descriptor {
-        get { return descriptor; }
-      }
-      private static pbr::FileDescriptor descriptor;
-
-      static RouteGuide() {
-        byte[] descriptorData = global::System.Convert.FromBase64String(
-            string.Concat(
-              "ChFyb3V0ZV9ndWlkZS5wcm90bxIKcm91dGVndWlkZSIsCgVQb2ludBIQCghs", 
-              "YXRpdHVkZRgBIAEoBRIRCglsb25naXR1ZGUYAiABKAUiSQoJUmVjdGFuZ2xl", 
-              "Eh0KAmxvGAEgASgLMhEucm91dGVndWlkZS5Qb2ludBIdCgJoaRgCIAEoCzIR", 
-              "LnJvdXRlZ3VpZGUuUG9pbnQiPAoHRmVhdHVyZRIMCgRuYW1lGAEgASgJEiMK", 
-              "CGxvY2F0aW9uGAIgASgLMhEucm91dGVndWlkZS5Qb2ludCJBCglSb3V0ZU5v", 
-              "dGUSIwoIbG9jYXRpb24YASABKAsyES5yb3V0ZWd1aWRlLlBvaW50Eg8KB21l", 
-              "c3NhZ2UYAiABKAkiYgoMUm91dGVTdW1tYXJ5EhMKC3BvaW50X2NvdW50GAEg", 
-              "ASgFEhUKDWZlYXR1cmVfY291bnQYAiABKAUSEAoIZGlzdGFuY2UYAyABKAUS", 
-              "FAoMZWxhcHNlZF90aW1lGAQgASgFMoUCCgpSb3V0ZUd1aWRlEjYKCkdldEZl", 
-              "YXR1cmUSES5yb3V0ZWd1aWRlLlBvaW50GhMucm91dGVndWlkZS5GZWF0dXJl", 
-              "IgASPgoMTGlzdEZlYXR1cmVzEhUucm91dGVndWlkZS5SZWN0YW5nbGUaEy5y", 
-              "b3V0ZWd1aWRlLkZlYXR1cmUiADABEj4KC1JlY29yZFJvdXRlEhEucm91dGVn", 
-              "dWlkZS5Qb2ludBoYLnJvdXRlZ3VpZGUuUm91dGVTdW1tYXJ5IgAoARI/CglS", 
-              "b3V0ZUNoYXQSFS5yb3V0ZWd1aWRlLlJvdXRlTm90ZRoVLnJvdXRlZ3VpZGUu", 
-              "Um91dGVOb3RlIgAoATABQg8KB2V4LmdycGOiAgNSVEdiBnByb3RvMw=="));
-        descriptor = pbr::FileDescriptor.InternalBuildGeneratedFileFrom(descriptorData,
-            new pbr::FileDescriptor[] { },
-            new pbr::GeneratedCodeInfo(null, new pbr::GeneratedCodeInfo[] {
-              new pbr::GeneratedCodeInfo(typeof(global::Routeguide.Point), new[]{ "Latitude", "Longitude" }, null, null, null),
-              new pbr::GeneratedCodeInfo(typeof(global::Routeguide.Rectangle), new[]{ "Lo", "Hi" }, null, null, null),
-              new pbr::GeneratedCodeInfo(typeof(global::Routeguide.Feature), new[]{ "Name", "Location" }, null, null, null),
-              new pbr::GeneratedCodeInfo(typeof(global::Routeguide.RouteNote), new[]{ "Location", "Message" }, null, null, null),
-              new pbr::GeneratedCodeInfo(typeof(global::Routeguide.RouteSummary), new[]{ "PointCount", "FeatureCount", "Distance", "ElapsedTime" }, null, null, null)
-            }));
-      }
-      #endregion
-
+    #region Descriptor
+    /// <summary>File descriptor for route_guide.proto</summary>
+    public static pbr::FileDescriptor Descriptor {
+      get { return descriptor; }
     }
+    private static pbr::FileDescriptor descriptor;
+
+    static RouteGuideReflection() {
+      byte[] descriptorData = global::System.Convert.FromBase64String(
+          string.Concat(
+            "ChFyb3V0ZV9ndWlkZS5wcm90bxIKcm91dGVndWlkZSIsCgVQb2ludBIQCghs",
+            "YXRpdHVkZRgBIAEoBRIRCglsb25naXR1ZGUYAiABKAUiSQoJUmVjdGFuZ2xl",
+            "Eh0KAmxvGAEgASgLMhEucm91dGVndWlkZS5Qb2ludBIdCgJoaRgCIAEoCzIR",
+            "LnJvdXRlZ3VpZGUuUG9pbnQiPAoHRmVhdHVyZRIMCgRuYW1lGAEgASgJEiMK",
+            "CGxvY2F0aW9uGAIgASgLMhEucm91dGVndWlkZS5Qb2ludCJBCglSb3V0ZU5v",
+            "dGUSIwoIbG9jYXRpb24YASABKAsyES5yb3V0ZWd1aWRlLlBvaW50Eg8KB21l",
+            "c3NhZ2UYAiABKAkiYgoMUm91dGVTdW1tYXJ5EhMKC3BvaW50X2NvdW50GAEg",
+            "ASgFEhUKDWZlYXR1cmVfY291bnQYAiABKAUSEAoIZGlzdGFuY2UYAyABKAUS",
+            "FAoMZWxhcHNlZF90aW1lGAQgASgFMoUCCgpSb3V0ZUd1aWRlEjYKCkdldEZl",
+            "YXR1cmUSES5yb3V0ZWd1aWRlLlBvaW50GhMucm91dGVndWlkZS5GZWF0dXJl",
+            "IgASPgoMTGlzdEZlYXR1cmVzEhUucm91dGVndWlkZS5SZWN0YW5nbGUaEy5y",
+            "b3V0ZWd1aWRlLkZlYXR1cmUiADABEj4KC1JlY29yZFJvdXRlEhEucm91dGVn",
+            "dWlkZS5Qb2ludBoYLnJvdXRlZ3VpZGUuUm91dGVTdW1tYXJ5IgAoARI/CglS",
+            "b3V0ZUNoYXQSFS5yb3V0ZWd1aWRlLlJvdXRlTm90ZRoVLnJvdXRlZ3VpZGUu",
+            "Um91dGVOb3RlIgAoATABQg8KB2V4LmdycGOiAgNSVEdiBnByb3RvMw=="));
+      descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
+          new pbr::FileDescriptor[] { },
+          new pbr::GeneratedCodeInfo(null, new pbr::GeneratedCodeInfo[] {
+            new pbr::GeneratedCodeInfo(typeof(global::Routeguide.Point), global::Routeguide.Point.Parser, new[]{ "Latitude", "Longitude" }, null, null, null),
+            new pbr::GeneratedCodeInfo(typeof(global::Routeguide.Rectangle), global::Routeguide.Rectangle.Parser, new[]{ "Lo", "Hi" }, null, null, null),
+            new pbr::GeneratedCodeInfo(typeof(global::Routeguide.Feature), global::Routeguide.Feature.Parser, new[]{ "Name", "Location" }, null, null, null),
+            new pbr::GeneratedCodeInfo(typeof(global::Routeguide.RouteNote), global::Routeguide.RouteNote.Parser, new[]{ "Location", "Message" }, null, null, null),
+            new pbr::GeneratedCodeInfo(typeof(global::Routeguide.RouteSummary), global::Routeguide.RouteSummary.Parser, new[]{ "PointCount", "FeatureCount", "Distance", "ElapsedTime" }, null, null, null)
+          }));
+    }
+    #endregion
+
   }
   #region Messages
+  /// <summary>
+  ///  Points are represented as latitude-longitude pairs in the E7 representation
+  ///  (degrees multiplied by 10**7 and rounded to the nearest integer).
+  ///  Latitudes should be in the range +/- 90 degrees and longitude should be in
+  ///  the range +/- 180 degrees (inclusive).
+  /// </summary>
   [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
   public sealed partial class Point : pb::IMessage<Point> {
     private static readonly pb::MessageParser<Point> _parser = new pb::MessageParser<Point>(() => new Point());
     public static pb::MessageParser<Point> Parser { get { return _parser; } }
 
     public static pbr::MessageDescriptor Descriptor {
-      get { return global::Routeguide.Proto.RouteGuide.Descriptor.MessageTypes[0]; }
+      get { return global::Routeguide.RouteGuideReflection.Descriptor.MessageTypes[0]; }
     }
 
     pbr::MessageDescriptor pb::IMessage.Descriptor {
@@ -81,6 +86,7 @@
       return new Point(this);
     }
 
+    /// <summary>Field number for the "latitude" field.</summary>
     public const int LatitudeFieldNumber = 1;
     private int latitude_;
     public int Latitude {
@@ -90,6 +96,7 @@
       }
     }
 
+    /// <summary>Field number for the "longitude" field.</summary>
     public const int LongitudeFieldNumber = 2;
     private int longitude_;
     public int Longitude {
@@ -123,7 +130,7 @@
     }
 
     public override string ToString() {
-      return pb::JsonFormatter.Default.Format(this);
+      return pb::JsonFormatter.ToDiagnosticString(this);
     }
 
     public void WriteTo(pb::CodedOutputStream output) {
@@ -181,13 +188,17 @@
 
   }
 
+  /// <summary>
+  ///  A latitude-longitude rectangle, represented as two diagonally opposite
+  ///  points "lo" and "hi".
+  /// </summary>
   [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
   public sealed partial class Rectangle : pb::IMessage<Rectangle> {
     private static readonly pb::MessageParser<Rectangle> _parser = new pb::MessageParser<Rectangle>(() => new Rectangle());
     public static pb::MessageParser<Rectangle> Parser { get { return _parser; } }
 
     public static pbr::MessageDescriptor Descriptor {
-      get { return global::Routeguide.Proto.RouteGuide.Descriptor.MessageTypes[1]; }
+      get { return global::Routeguide.RouteGuideReflection.Descriptor.MessageTypes[1]; }
     }
 
     pbr::MessageDescriptor pb::IMessage.Descriptor {
@@ -209,8 +220,12 @@
       return new Rectangle(this);
     }
 
+    /// <summary>Field number for the "lo" field.</summary>
     public const int LoFieldNumber = 1;
     private global::Routeguide.Point lo_;
+    /// <summary>
+    ///  One corner of the rectangle.
+    /// </summary>
     public global::Routeguide.Point Lo {
       get { return lo_; }
       set {
@@ -218,8 +233,12 @@
       }
     }
 
+    /// <summary>Field number for the "hi" field.</summary>
     public const int HiFieldNumber = 2;
     private global::Routeguide.Point hi_;
+    /// <summary>
+    ///  The other corner of the rectangle.
+    /// </summary>
     public global::Routeguide.Point Hi {
       get { return hi_; }
       set {
@@ -251,7 +270,7 @@
     }
 
     public override string ToString() {
-      return pb::JsonFormatter.Default.Format(this);
+      return pb::JsonFormatter.ToDiagnosticString(this);
     }
 
     public void WriteTo(pb::CodedOutputStream output) {
@@ -321,13 +340,18 @@
 
   }
 
+  /// <summary>
+  ///  A feature names something at a given point.
+  ///
+  ///  If a feature could not be named, the name is empty.
+  /// </summary>
   [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
   public sealed partial class Feature : pb::IMessage<Feature> {
     private static readonly pb::MessageParser<Feature> _parser = new pb::MessageParser<Feature>(() => new Feature());
     public static pb::MessageParser<Feature> Parser { get { return _parser; } }
 
     public static pbr::MessageDescriptor Descriptor {
-      get { return global::Routeguide.Proto.RouteGuide.Descriptor.MessageTypes[2]; }
+      get { return global::Routeguide.RouteGuideReflection.Descriptor.MessageTypes[2]; }
     }
 
     pbr::MessageDescriptor pb::IMessage.Descriptor {
@@ -349,8 +373,12 @@
       return new Feature(this);
     }
 
+    /// <summary>Field number for the "name" field.</summary>
     public const int NameFieldNumber = 1;
     private string name_ = "";
+    /// <summary>
+    ///  The name of the feature.
+    /// </summary>
     public string Name {
       get { return name_; }
       set {
@@ -358,8 +386,12 @@
       }
     }
 
+    /// <summary>Field number for the "location" field.</summary>
     public const int LocationFieldNumber = 2;
     private global::Routeguide.Point location_;
+    /// <summary>
+    ///  The point where the feature is detected.
+    /// </summary>
     public global::Routeguide.Point Location {
       get { return location_; }
       set {
@@ -391,7 +423,7 @@
     }
 
     public override string ToString() {
-      return pb::JsonFormatter.Default.Format(this);
+      return pb::JsonFormatter.ToDiagnosticString(this);
     }
 
     public void WriteTo(pb::CodedOutputStream output) {
@@ -455,13 +487,16 @@
 
   }
 
+  /// <summary>
+  ///  A RouteNote is a message sent while at a given point.
+  /// </summary>
   [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
   public sealed partial class RouteNote : pb::IMessage<RouteNote> {
     private static readonly pb::MessageParser<RouteNote> _parser = new pb::MessageParser<RouteNote>(() => new RouteNote());
     public static pb::MessageParser<RouteNote> Parser { get { return _parser; } }
 
     public static pbr::MessageDescriptor Descriptor {
-      get { return global::Routeguide.Proto.RouteGuide.Descriptor.MessageTypes[3]; }
+      get { return global::Routeguide.RouteGuideReflection.Descriptor.MessageTypes[3]; }
     }
 
     pbr::MessageDescriptor pb::IMessage.Descriptor {
@@ -483,8 +518,12 @@
       return new RouteNote(this);
     }
 
+    /// <summary>Field number for the "location" field.</summary>
     public const int LocationFieldNumber = 1;
     private global::Routeguide.Point location_;
+    /// <summary>
+    ///  The location from which the message is sent.
+    /// </summary>
     public global::Routeguide.Point Location {
       get { return location_; }
       set {
@@ -492,8 +531,12 @@
       }
     }
 
+    /// <summary>Field number for the "message" field.</summary>
     public const int MessageFieldNumber = 2;
     private string message_ = "";
+    /// <summary>
+    ///  The message to be sent.
+    /// </summary>
     public string Message {
       get { return message_; }
       set {
@@ -525,7 +568,7 @@
     }
 
     public override string ToString() {
-      return pb::JsonFormatter.Default.Format(this);
+      return pb::JsonFormatter.ToDiagnosticString(this);
     }
 
     public void WriteTo(pb::CodedOutputStream output) {
@@ -589,13 +632,20 @@
 
   }
 
+  /// <summary>
+  ///  A RouteSummary is received in response to a RecordRoute rpc.
+  ///
+  ///  It contains the number of individual points received, the number of
+  ///  detected features, and the total distance covered as the cumulative sum of
+  ///  the distance between each point.
+  /// </summary>
   [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
   public sealed partial class RouteSummary : pb::IMessage<RouteSummary> {
     private static readonly pb::MessageParser<RouteSummary> _parser = new pb::MessageParser<RouteSummary>(() => new RouteSummary());
     public static pb::MessageParser<RouteSummary> Parser { get { return _parser; } }
 
     public static pbr::MessageDescriptor Descriptor {
-      get { return global::Routeguide.Proto.RouteGuide.Descriptor.MessageTypes[4]; }
+      get { return global::Routeguide.RouteGuideReflection.Descriptor.MessageTypes[4]; }
     }
 
     pbr::MessageDescriptor pb::IMessage.Descriptor {
@@ -619,8 +669,12 @@
       return new RouteSummary(this);
     }
 
+    /// <summary>Field number for the "point_count" field.</summary>
     public const int PointCountFieldNumber = 1;
     private int pointCount_;
+    /// <summary>
+    ///  The number of points received.
+    /// </summary>
     public int PointCount {
       get { return pointCount_; }
       set {
@@ -628,8 +682,12 @@
       }
     }
 
+    /// <summary>Field number for the "feature_count" field.</summary>
     public const int FeatureCountFieldNumber = 2;
     private int featureCount_;
+    /// <summary>
+    ///  The number of known features passed while traversing the route.
+    /// </summary>
     public int FeatureCount {
       get { return featureCount_; }
       set {
@@ -637,8 +695,12 @@
       }
     }
 
+    /// <summary>Field number for the "distance" field.</summary>
     public const int DistanceFieldNumber = 3;
     private int distance_;
+    /// <summary>
+    ///  The distance covered in metres.
+    /// </summary>
     public int Distance {
       get { return distance_; }
       set {
@@ -646,8 +708,12 @@
       }
     }
 
+    /// <summary>Field number for the "elapsed_time" field.</summary>
     public const int ElapsedTimeFieldNumber = 4;
     private int elapsedTime_;
+    /// <summary>
+    ///  The duration of the traversal in seconds.
+    /// </summary>
     public int ElapsedTime {
       get { return elapsedTime_; }
       set {
@@ -683,7 +749,7 @@
     }
 
     public override string ToString() {
-      return pb::JsonFormatter.Default.Format(this);
+      return pb::JsonFormatter.ToDiagnosticString(this);
     }
 
     public void WriteTo(pb::CodedOutputStream output) {
diff --git a/examples/csharp/route_guide/RouteGuide/RouteGuide.csproj b/examples/csharp/route_guide/RouteGuide/RouteGuide.csproj
index 3a2a29c..1fbf1ce 100644
--- a/examples/csharp/route_guide/RouteGuide/RouteGuide.csproj
+++ b/examples/csharp/route_guide/RouteGuide/RouteGuide.csproj
@@ -11,7 +11,7 @@
     <AssemblyName>RouteGuide</AssemblyName>
     <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
     <FileAlignment>512</FileAlignment>
-    <NuGetPackageImportStamp>68b3dd23</NuGetPackageImportStamp>
+    <NuGetPackageImportStamp>5b6d924a</NuGetPackageImportStamp>
   </PropertyGroup>
   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
     <DebugSymbols>true</DebugSymbols>
@@ -31,11 +31,13 @@
     <WarningLevel>4</WarningLevel>
   </PropertyGroup>
   <ItemGroup>
-    <Reference Include="Google.Protobuf">
-      <HintPath>..\packages\Google.Protobuf.3.0.0-alpha4\lib\portable-net45+netcore45+wpa81+wp8\Google.Protobuf.dll</HintPath>
+    <Reference Include="Google.Protobuf, Version=3.0.0.0, Culture=neutral, PublicKeyToken=a7d26565bac4d604, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\packages\Google.Protobuf.3.0.0-beta2\lib\portable-net45+netcore45+wpa81+wp8\Google.Protobuf.dll</HintPath>
     </Reference>
-    <Reference Include="Grpc.Core">
-      <HintPath>..\packages\Grpc.Core.0.12.0\lib\net45\Grpc.Core.dll</HintPath>
+    <Reference Include="Grpc.Core, Version=0.12.0.0, Culture=neutral, PublicKeyToken=d754f35622e28bad, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\packages\Grpc.Core.0.13.0\lib\net45\Grpc.Core.dll</HintPath>
     </Reference>
     <Reference Include="Newtonsoft.Json, Version=7.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
       <SpecificVersion>False</SpecificVersion>
@@ -65,17 +67,13 @@
     </None>
   </ItemGroup>
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
-  <Import Project="..\packages\grpc.dependencies.zlib.redist.1.2.8.10\build\portable-net45+netcore45+wpa81+wp8\grpc.dependencies.zlib.redist.targets" Condition="Exists('..\packages\grpc.dependencies.zlib.redist.1.2.8.10\build\portable-net45+netcore45+wpa81+wp8\grpc.dependencies.zlib.redist.targets')" />
+  <Import Project="..\packages\grpc.native.csharp.0.13.0\build\portable-net45+netcore45+wpa81+wp8\grpc.native.csharp.targets" Condition="Exists('..\packages\grpc.native.csharp.0.13.0\build\portable-net45+netcore45+wpa81+wp8\grpc.native.csharp.targets')" />
   <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
     <PropertyGroup>
       <ErrorText>This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them.  For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
     </PropertyGroup>
-    <Error Condition="!Exists('..\packages\grpc.dependencies.zlib.redist.1.2.8.10\build\portable-net45+netcore45+wpa81+wp8\grpc.dependencies.zlib.redist.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\grpc.dependencies.zlib.redist.1.2.8.10\build\portable-net45+netcore45+wpa81+wp8\grpc.dependencies.zlib.redist.targets'))" />
-    <Error Condition="!Exists('..\packages\grpc.dependencies.openssl.redist.1.0.204.1\build\portable-net45+netcore45+wpa81+wp8\grpc.dependencies.openssl.redist.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\grpc.dependencies.openssl.redist.1.0.204.1\build\portable-net45+netcore45+wpa81+wp8\grpc.dependencies.openssl.redist.targets'))" />
-    <Error Condition="!Exists('..\packages\grpc.native.csharp.0.12.0\build\portable-net45+netcore45+wpa81+wp8\grpc.native.csharp.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\grpc.native.csharp.0.12.0\build\portable-net45+netcore45+wpa81+wp8\grpc.native.csharp.targets'))" />
+    <Error Condition="!Exists('..\packages\grpc.native.csharp.0.13.0\build\portable-net45+netcore45+wpa81+wp8\grpc.native.csharp.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\grpc.native.csharp.0.13.0\build\portable-net45+netcore45+wpa81+wp8\grpc.native.csharp.targets'))" />
   </Target>
-  <Import Project="..\packages\grpc.dependencies.openssl.redist.1.0.204.1\build\portable-net45+netcore45+wpa81+wp8\grpc.dependencies.openssl.redist.targets" Condition="Exists('..\packages\grpc.dependencies.openssl.redist.1.0.204.1\build\portable-net45+netcore45+wpa81+wp8\grpc.dependencies.openssl.redist.targets')" />
-  <Import Project="..\packages\grpc.native.csharp.0.12.0\build\portable-net45+netcore45+wpa81+wp8\grpc.native.csharp.targets" Condition="Exists('..\packages\grpc.native.csharp.0.12.0\build\portable-net45+netcore45+wpa81+wp8\grpc.native.csharp.targets')" />
   <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
        Other similar extension points exist, see Microsoft.Common.targets.
   <Target Name="BeforeBuild">
diff --git a/examples/csharp/route_guide/RouteGuide/RouteGuideGrpc.cs b/examples/csharp/route_guide/RouteGuide/RouteGuideGrpc.cs
index d60256f..66d1c07 100644
--- a/examples/csharp/route_guide/RouteGuide/RouteGuideGrpc.cs
+++ b/examples/csharp/route_guide/RouteGuide/RouteGuideGrpc.cs
@@ -49,7 +49,7 @@
     // service descriptor
     public static global::Google.Protobuf.Reflection.ServiceDescriptor Descriptor
     {
-      get { return global::Routeguide.Proto.RouteGuide.Descriptor.Services[0]; }
+      get { return global::Routeguide.RouteGuideReflection.Descriptor.Services[0]; }
     }
 
     // client interface
diff --git a/examples/csharp/route_guide/RouteGuide/packages.config b/examples/csharp/route_guide/RouteGuide/packages.config
index 8717315..e4e2109 100644
--- a/examples/csharp/route_guide/RouteGuide/packages.config
+++ b/examples/csharp/route_guide/RouteGuide/packages.config
@@ -1,11 +1,9 @@
 <?xml version="1.0" encoding="utf-8"?>
 <packages>
-  <package id="Google.Protobuf" version="3.0.0-alpha4" targetFramework="net45" />
-  <package id="Grpc" version="0.12.0" targetFramework="net45" />
-  <package id="Grpc.Core" version="0.12.0" targetFramework="net45" />
-  <package id="grpc.dependencies.openssl.redist" version="1.0.204.1" targetFramework="net45" />
-  <package id="grpc.dependencies.zlib.redist" version="1.2.8.10" targetFramework="net45" />
-  <package id="grpc.native.csharp" version="0.12.0" targetFramework="net45" />
+  <package id="Google.Protobuf" version="3.0.0-beta2" targetFramework="net45" />
+  <package id="Grpc" version="0.13.0" targetFramework="net45" />
+  <package id="Grpc.Core" version="0.13.0" targetFramework="net45" />
+  <package id="grpc.native.csharp" version="0.13.0" targetFramework="net45" />
   <package id="Ix-Async" version="1.2.3" targetFramework="net45" />
   <package id="Newtonsoft.Json" version="7.0.1" targetFramework="net45" />
 </packages>
\ No newline at end of file
diff --git a/examples/csharp/route_guide/RouteGuideClient/RouteGuideClient.csproj b/examples/csharp/route_guide/RouteGuideClient/RouteGuideClient.csproj
index 89e5025..f55627e 100644
--- a/examples/csharp/route_guide/RouteGuideClient/RouteGuideClient.csproj
+++ b/examples/csharp/route_guide/RouteGuideClient/RouteGuideClient.csproj
@@ -11,7 +11,7 @@
     <AssemblyName>RouteGuideClient</AssemblyName>
     <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
     <FileAlignment>512</FileAlignment>
-    <NuGetPackageImportStamp>f5579f73</NuGetPackageImportStamp>
+    <NuGetPackageImportStamp>69015b00</NuGetPackageImportStamp>
   </PropertyGroup>
   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
     <PlatformTarget>AnyCPU</PlatformTarget>
@@ -33,11 +33,13 @@
     <WarningLevel>4</WarningLevel>
   </PropertyGroup>
   <ItemGroup>
-    <Reference Include="Google.Protobuf">
-      <HintPath>..\packages\Google.Protobuf.3.0.0-alpha4\lib\portable-net45+netcore45+wpa81+wp8\Google.Protobuf.dll</HintPath>
+    <Reference Include="Google.Protobuf, Version=3.0.0.0, Culture=neutral, PublicKeyToken=a7d26565bac4d604, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\packages\Google.Protobuf.3.0.0-beta2\lib\portable-net45+netcore45+wpa81+wp8\Google.Protobuf.dll</HintPath>
     </Reference>
-    <Reference Include="Grpc.Core">
-      <HintPath>..\packages\Grpc.Core.0.12.0\lib\net45\Grpc.Core.dll</HintPath>
+    <Reference Include="Grpc.Core, Version=0.12.0.0, Culture=neutral, PublicKeyToken=d754f35622e28bad, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\packages\Grpc.Core.0.13.0\lib\net45\Grpc.Core.dll</HintPath>
     </Reference>
     <Reference Include="Newtonsoft.Json, Version=7.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
       <SpecificVersion>False</SpecificVersion>
@@ -68,17 +70,13 @@
     </ProjectReference>
   </ItemGroup>
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
-  <Import Project="..\packages\grpc.dependencies.zlib.redist.1.2.8.10\build\portable-net45+netcore45+wpa81+wp8\grpc.dependencies.zlib.redist.targets" Condition="Exists('..\packages\grpc.dependencies.zlib.redist.1.2.8.10\build\portable-net45+netcore45+wpa81+wp8\grpc.dependencies.zlib.redist.targets')" />
+  <Import Project="..\packages\grpc.native.csharp.0.13.0\build\portable-net45+netcore45+wpa81+wp8\grpc.native.csharp.targets" Condition="Exists('..\packages\grpc.native.csharp.0.13.0\build\portable-net45+netcore45+wpa81+wp8\grpc.native.csharp.targets')" />
   <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
     <PropertyGroup>
       <ErrorText>This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them.  For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
     </PropertyGroup>
-    <Error Condition="!Exists('..\packages\grpc.dependencies.zlib.redist.1.2.8.10\build\portable-net45+netcore45+wpa81+wp8\grpc.dependencies.zlib.redist.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\grpc.dependencies.zlib.redist.1.2.8.10\build\portable-net45+netcore45+wpa81+wp8\grpc.dependencies.zlib.redist.targets'))" />
-    <Error Condition="!Exists('..\packages\grpc.dependencies.openssl.redist.1.0.204.1\build\portable-net45+netcore45+wpa81+wp8\grpc.dependencies.openssl.redist.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\grpc.dependencies.openssl.redist.1.0.204.1\build\portable-net45+netcore45+wpa81+wp8\grpc.dependencies.openssl.redist.targets'))" />
-    <Error Condition="!Exists('..\packages\grpc.native.csharp.0.12.0\build\portable-net45+netcore45+wpa81+wp8\grpc.native.csharp.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\grpc.native.csharp.0.12.0\build\portable-net45+netcore45+wpa81+wp8\grpc.native.csharp.targets'))" />
+    <Error Condition="!Exists('..\packages\grpc.native.csharp.0.13.0\build\portable-net45+netcore45+wpa81+wp8\grpc.native.csharp.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\grpc.native.csharp.0.13.0\build\portable-net45+netcore45+wpa81+wp8\grpc.native.csharp.targets'))" />
   </Target>
-  <Import Project="..\packages\grpc.dependencies.openssl.redist.1.0.204.1\build\portable-net45+netcore45+wpa81+wp8\grpc.dependencies.openssl.redist.targets" Condition="Exists('..\packages\grpc.dependencies.openssl.redist.1.0.204.1\build\portable-net45+netcore45+wpa81+wp8\grpc.dependencies.openssl.redist.targets')" />
-  <Import Project="..\packages\grpc.native.csharp.0.12.0\build\portable-net45+netcore45+wpa81+wp8\grpc.native.csharp.targets" Condition="Exists('..\packages\grpc.native.csharp.0.12.0\build\portable-net45+netcore45+wpa81+wp8\grpc.native.csharp.targets')" />
   <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
        Other similar extension points exist, see Microsoft.Common.targets.
   <Target Name="BeforeBuild">
diff --git a/examples/csharp/route_guide/RouteGuideClient/packages.config b/examples/csharp/route_guide/RouteGuideClient/packages.config
index 8717315..e4e2109 100644
--- a/examples/csharp/route_guide/RouteGuideClient/packages.config
+++ b/examples/csharp/route_guide/RouteGuideClient/packages.config
@@ -1,11 +1,9 @@
 <?xml version="1.0" encoding="utf-8"?>
 <packages>
-  <package id="Google.Protobuf" version="3.0.0-alpha4" targetFramework="net45" />
-  <package id="Grpc" version="0.12.0" targetFramework="net45" />
-  <package id="Grpc.Core" version="0.12.0" targetFramework="net45" />
-  <package id="grpc.dependencies.openssl.redist" version="1.0.204.1" targetFramework="net45" />
-  <package id="grpc.dependencies.zlib.redist" version="1.2.8.10" targetFramework="net45" />
-  <package id="grpc.native.csharp" version="0.12.0" targetFramework="net45" />
+  <package id="Google.Protobuf" version="3.0.0-beta2" targetFramework="net45" />
+  <package id="Grpc" version="0.13.0" targetFramework="net45" />
+  <package id="Grpc.Core" version="0.13.0" targetFramework="net45" />
+  <package id="grpc.native.csharp" version="0.13.0" targetFramework="net45" />
   <package id="Ix-Async" version="1.2.3" targetFramework="net45" />
   <package id="Newtonsoft.Json" version="7.0.1" targetFramework="net45" />
 </packages>
\ No newline at end of file
diff --git a/examples/csharp/route_guide/RouteGuideServer/RouteGuideServer.csproj b/examples/csharp/route_guide/RouteGuideServer/RouteGuideServer.csproj
index 2e93062..873556d 100644
--- a/examples/csharp/route_guide/RouteGuideServer/RouteGuideServer.csproj
+++ b/examples/csharp/route_guide/RouteGuideServer/RouteGuideServer.csproj
@@ -11,7 +11,7 @@
     <AssemblyName>RouteGuideServer</AssemblyName>
     <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
     <FileAlignment>512</FileAlignment>
-    <NuGetPackageImportStamp>89e15444</NuGetPackageImportStamp>
+    <NuGetPackageImportStamp>656158d8</NuGetPackageImportStamp>
   </PropertyGroup>
   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
     <PlatformTarget>AnyCPU</PlatformTarget>
@@ -33,11 +33,13 @@
     <WarningLevel>4</WarningLevel>
   </PropertyGroup>
   <ItemGroup>
-    <Reference Include="Google.Protobuf">
-      <HintPath>..\packages\Google.Protobuf.3.0.0-alpha4\lib\portable-net45+netcore45+wpa81+wp8\Google.Protobuf.dll</HintPath>
+    <Reference Include="Google.Protobuf, Version=3.0.0.0, Culture=neutral, PublicKeyToken=a7d26565bac4d604, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\packages\Google.Protobuf.3.0.0-beta2\lib\portable-net45+netcore45+wpa81+wp8\Google.Protobuf.dll</HintPath>
     </Reference>
-    <Reference Include="Grpc.Core">
-      <HintPath>..\packages\Grpc.Core.0.12.0\lib\net45\Grpc.Core.dll</HintPath>
+    <Reference Include="Grpc.Core, Version=0.12.0.0, Culture=neutral, PublicKeyToken=d754f35622e28bad, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\packages\Grpc.Core.0.13.0\lib\net45\Grpc.Core.dll</HintPath>
     </Reference>
     <Reference Include="Newtonsoft.Json, Version=7.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
       <SpecificVersion>False</SpecificVersion>
@@ -69,17 +71,13 @@
     </ProjectReference>
   </ItemGroup>
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
-  <Import Project="..\packages\grpc.dependencies.zlib.redist.1.2.8.10\build\portable-net45+netcore45+wpa81+wp8\grpc.dependencies.zlib.redist.targets" Condition="Exists('..\packages\grpc.dependencies.zlib.redist.1.2.8.10\build\portable-net45+netcore45+wpa81+wp8\grpc.dependencies.zlib.redist.targets')" />
+  <Import Project="..\packages\grpc.native.csharp.0.13.0\build\portable-net45+netcore45+wpa81+wp8\grpc.native.csharp.targets" Condition="Exists('..\packages\grpc.native.csharp.0.13.0\build\portable-net45+netcore45+wpa81+wp8\grpc.native.csharp.targets')" />
   <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
     <PropertyGroup>
       <ErrorText>This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them.  For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
     </PropertyGroup>
-    <Error Condition="!Exists('..\packages\grpc.dependencies.zlib.redist.1.2.8.10\build\portable-net45+netcore45+wpa81+wp8\grpc.dependencies.zlib.redist.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\grpc.dependencies.zlib.redist.1.2.8.10\build\portable-net45+netcore45+wpa81+wp8\grpc.dependencies.zlib.redist.targets'))" />
-    <Error Condition="!Exists('..\packages\grpc.dependencies.openssl.redist.1.0.204.1\build\portable-net45+netcore45+wpa81+wp8\grpc.dependencies.openssl.redist.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\grpc.dependencies.openssl.redist.1.0.204.1\build\portable-net45+netcore45+wpa81+wp8\grpc.dependencies.openssl.redist.targets'))" />
-    <Error Condition="!Exists('..\packages\grpc.native.csharp.0.12.0\build\portable-net45+netcore45+wpa81+wp8\grpc.native.csharp.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\grpc.native.csharp.0.12.0\build\portable-net45+netcore45+wpa81+wp8\grpc.native.csharp.targets'))" />
+    <Error Condition="!Exists('..\packages\grpc.native.csharp.0.13.0\build\portable-net45+netcore45+wpa81+wp8\grpc.native.csharp.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\grpc.native.csharp.0.13.0\build\portable-net45+netcore45+wpa81+wp8\grpc.native.csharp.targets'))" />
   </Target>
-  <Import Project="..\packages\grpc.dependencies.openssl.redist.1.0.204.1\build\portable-net45+netcore45+wpa81+wp8\grpc.dependencies.openssl.redist.targets" Condition="Exists('..\packages\grpc.dependencies.openssl.redist.1.0.204.1\build\portable-net45+netcore45+wpa81+wp8\grpc.dependencies.openssl.redist.targets')" />
-  <Import Project="..\packages\grpc.native.csharp.0.12.0\build\portable-net45+netcore45+wpa81+wp8\grpc.native.csharp.targets" Condition="Exists('..\packages\grpc.native.csharp.0.12.0\build\portable-net45+netcore45+wpa81+wp8\grpc.native.csharp.targets')" />
   <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
        Other similar extension points exist, see Microsoft.Common.targets.
   <Target Name="BeforeBuild">
diff --git a/examples/csharp/route_guide/RouteGuideServer/packages.config b/examples/csharp/route_guide/RouteGuideServer/packages.config
index 8717315..e4e2109 100644
--- a/examples/csharp/route_guide/RouteGuideServer/packages.config
+++ b/examples/csharp/route_guide/RouteGuideServer/packages.config
@@ -1,11 +1,9 @@
 <?xml version="1.0" encoding="utf-8"?>
 <packages>
-  <package id="Google.Protobuf" version="3.0.0-alpha4" targetFramework="net45" />
-  <package id="Grpc" version="0.12.0" targetFramework="net45" />
-  <package id="Grpc.Core" version="0.12.0" targetFramework="net45" />
-  <package id="grpc.dependencies.openssl.redist" version="1.0.204.1" targetFramework="net45" />
-  <package id="grpc.dependencies.zlib.redist" version="1.2.8.10" targetFramework="net45" />
-  <package id="grpc.native.csharp" version="0.12.0" targetFramework="net45" />
+  <package id="Google.Protobuf" version="3.0.0-beta2" targetFramework="net45" />
+  <package id="Grpc" version="0.13.0" targetFramework="net45" />
+  <package id="Grpc.Core" version="0.13.0" targetFramework="net45" />
+  <package id="grpc.native.csharp" version="0.13.0" targetFramework="net45" />
   <package id="Ix-Async" version="1.2.3" targetFramework="net45" />
   <package id="Newtonsoft.Json" version="7.0.1" targetFramework="net45" />
 </packages>
\ No newline at end of file
diff --git a/examples/csharp/route_guide/generate_protos.bat b/examples/csharp/route_guide/generate_protos.bat
index fad63ef..d9cd021 100644
--- a/examples/csharp/route_guide/generate_protos.bat
+++ b/examples/csharp/route_guide/generate_protos.bat
@@ -5,6 +5,6 @@
 @rem enter this directory
 cd /d %~dp0
 
-packages\Google.Protobuf.3.0.0-alpha4\tools\protoc.exe -I../../protos --csharp_out RouteGuide  ../../protos/route_guide.proto --grpc_out RouteGuide --plugin=protoc-gen-grpc=packages\Grpc.Tools.0.12.0\tools\grpc_csharp_plugin.exe
+packages\Google.Protobuf.3.0.0-beta2\tools\protoc.exe -I../../protos --csharp_out RouteGuide  ../../protos/route_guide.proto --grpc_out RouteGuide --plugin=protoc-gen-grpc=packages\Grpc.Tools.0.13.0\tools\grpc_csharp_plugin.exe
 
 endlocal
\ No newline at end of file
diff --git a/examples/python/README.md b/examples/python/README.md
index 7b48c82..b57da8f 100644
--- a/examples/python/README.md
+++ b/examples/python/README.md
@@ -6,24 +6,18 @@
 For this sample, we've already generated the server and client stubs from
 [helloworld.proto][] and we'll be using a specific reference platform.
 
-Prerequisites
--------------
 
-- Debian 8.2 "Jessie" platform with `root` access
-- `git`
-- `python2.7`
-- `pip`
-- Python development headers
-
-Set-up
--------
+Install gRPC:
   ```sh
-  $ # install the gRPC Core:
-  $ sudo apt-get install libgrpc-dev
-  $ # install gRPC Python:
-  $ sudo pip install -U grpcio==0.11.0b1
-  $ # Since this "hello, world" example uses protocol buffers:
-  $ sudo pip install -U protobuf==3.0.0a3
+  $ pip install grpcio
+```
+Or, to install it system wide:
+```sh
+	$ sudo pip install grpcio
+```
+
+Download the example
+```sh
   $ # Clone the repository to get the example code:
   $ git clone https://github.com/grpc/grpc
   $ # Navigate to the "hello, world" Python example:
diff --git a/examples/python/helloworld/run_client.sh b/examples/python/helloworld/run_client.sh
deleted file mode 100755
index 1c0ce02..0000000
--- a/examples/python/helloworld/run_client.sh
+++ /dev/null
@@ -1,36 +0,0 @@
-#!/bin/bash
-# Copyright 2015, Google Inc.
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are
-# met:
-#
-#     * Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-#     * Redistributions in binary form must reproduce the above
-# copyright notice, this list of conditions and the following disclaimer
-# in the documentation and/or other materials provided with the
-# distribution.
-#     * Neither the name of Google Inc. nor the names of its
-# contributors may be used to endorse or promote products derived from
-# this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-# This is where you have cloned out the https://github.com/grpc/grpc repository
-# And built gRPC Python.
-# ADJUST THIS PATH TO WHERE YOUR ACTUAL LOCATION IS
-GRPC_ROOT=~/github/grpc
-
-$GRPC_ROOT/python2.7_virtual_environment/bin/python greeter_client.py
diff --git a/examples/python/helloworld/run_server.sh b/examples/python/helloworld/run_server.sh
deleted file mode 100755
index 82ebb1f..0000000
--- a/examples/python/helloworld/run_server.sh
+++ /dev/null
@@ -1,37 +0,0 @@
-#!/bin/bash
-# Copyright 2015, Google Inc.
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are
-# met:
-#
-#     * Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-#     * Redistributions in binary form must reproduce the above
-# copyright notice, this list of conditions and the following disclaimer
-# in the documentation and/or other materials provided with the
-# distribution.
-#     * Neither the name of Google Inc. nor the names of its
-# contributors may be used to endorse or promote products derived from
-# this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-# This is where you have cloned out the https://github.com/grpc/grpc repository
-# And built gRPC Python.
-# ADJUST THIS PATH TO WHERE YOUR ACTUAL LOCATION IS
-GRPC_ROOT=~/github/grpc
-
-$GRPC_ROOT/python2.7_virtual_environment/bin/python greeter_server.py
-
diff --git a/examples/python/route_guide/run_server.sh b/examples/python/route_guide/run_server.sh
deleted file mode 100755
index 7b1a764..0000000
--- a/examples/python/route_guide/run_server.sh
+++ /dev/null
@@ -1,36 +0,0 @@
-#!/bin/bash
-# Copyright 2015, Google Inc.
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are
-# met:
-#
-#     * Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-#     * Redistributions in binary form must reproduce the above
-# copyright notice, this list of conditions and the following disclaimer
-# in the documentation and/or other materials provided with the
-# distribution.
-#     * Neither the name of Google Inc. nor the names of its
-# contributors may be used to endorse or promote products derived from
-# this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-# This is where you have cloned out the https://github.com/grpc/grpc repository
-# And built gRPC Python.
-# ADJUST THIS PATH TO WHERE YOUR ACTUAL LOCATION IS
-GRPC_ROOT=~/github/grpc
-
-$GRPC_ROOT/python2.7_virtual_environment/bin/python -B route_guide_server.py
diff --git a/gRPC.podspec b/gRPC.podspec
index d02ee67..e0fcdae 100644
--- a/gRPC.podspec
+++ b/gRPC.podspec
@@ -66,13 +66,14 @@
     ss.source_files = 'src/core/profiling/timers.h',
                       'src/core/support/block_annotate.h',
                       'src/core/support/env.h',
-                      'src/core/support/file.h',
+                      'src/core/support/load_file.h',
                       'src/core/support/murmur_hash.h',
                       'src/core/support/stack_lockfree.h',
                       'src/core/support/string.h',
                       'src/core/support/string_win32.h',
                       'src/core/support/thd_internal.h',
                       'src/core/support/time_precise.h',
+                      'src/core/support/tmpfile.h',
                       'include/grpc/support/alloc.h',
                       'include/grpc/support/atm.h',
                       'include/grpc/support/atm_gcc_atomic.h',
@@ -127,11 +128,9 @@
                       'src/core/support/env_linux.c',
                       'src/core/support/env_posix.c',
                       'src/core/support/env_win32.c',
-                      'src/core/support/file.c',
-                      'src/core/support/file_posix.c',
-                      'src/core/support/file_win32.c',
                       'src/core/support/histogram.c',
                       'src/core/support/host_port.c',
+                      'src/core/support/load_file.c',
                       'src/core/support/log.c',
                       'src/core/support/log_android.c',
                       'src/core/support/log_linux.c',
@@ -157,21 +156,9 @@
                       'src/core/support/time_precise.c',
                       'src/core/support/time_win32.c',
                       'src/core/support/tls_pthread.c',
+                      'src/core/support/tmpfile_posix.c',
+                      'src/core/support/tmpfile_win32.c',
                       'src/core/support/wrap_memcpy.c',
-                      'src/core/security/auth_filters.h',
-                      'src/core/security/base64.h',
-                      'src/core/security/credentials.h',
-                      'src/core/security/handshake.h',
-                      'src/core/security/json_token.h',
-                      'src/core/security/jwt_verifier.h',
-                      'src/core/security/secure_endpoint.h',
-                      'src/core/security/security_connector.h',
-                      'src/core/security/security_context.h',
-                      'src/core/tsi/fake_transport_security.h',
-                      'src/core/tsi/ssl_transport_security.h',
-                      'src/core/tsi/ssl_types.h',
-                      'src/core/tsi/transport_security.h',
-                      'src/core/tsi/transport_security_interface.h',
                       'src/core/census/grpc_filter.h',
                       'src/core/channel/channel_args.h',
                       'src/core/channel/channel_stack.h',
@@ -186,6 +173,7 @@
                       'src/core/client_config/client_config.h',
                       'src/core/client_config/connector.h',
                       'src/core/client_config/initial_connect_string.h',
+                      'src/core/client_config/lb_policies/load_balancer_api.h',
                       'src/core/client_config/lb_policies/pick_first.h',
                       'src/core/client_config/lb_policies/round_robin.h',
                       'src/core/client_config/lb_policy.h',
@@ -236,7 +224,6 @@
                       'src/core/iomgr/time_averaged_stats.h',
                       'src/core/iomgr/timer.h',
                       'src/core/iomgr/timer_heap.h',
-                      'src/core/iomgr/timer_internal.h',
                       'src/core/iomgr/udp_server.h',
                       'src/core/iomgr/wakeup_fd_pipe.h',
                       'src/core/iomgr/wakeup_fd_posix.h',
@@ -247,6 +234,7 @@
                       'src/core/json/json_common.h',
                       'src/core/json/json_reader.h',
                       'src/core/json/json_writer.h',
+                      'src/core/proto/grpc/lb/v0/load_balancer.pb.h',
                       'src/core/statistics/census_interface.h',
                       'src/core/statistics/census_rpc_stats.h',
                       'src/core/surface/api_trace.h',
@@ -286,9 +274,27 @@
                       'src/core/transport/static_metadata.h',
                       'src/core/transport/transport.h',
                       'src/core/transport/transport_impl.h',
+                      'src/core/security/auth_filters.h',
+                      'src/core/security/b64.h',
+                      'src/core/security/credentials.h',
+                      'src/core/security/handshake.h',
+                      'src/core/security/json_token.h',
+                      'src/core/security/jwt_verifier.h',
+                      'src/core/security/secure_endpoint.h',
+                      'src/core/security/security_connector.h',
+                      'src/core/security/security_context.h',
+                      'src/core/tsi/fake_transport_security.h',
+                      'src/core/tsi/ssl_transport_security.h',
+                      'src/core/tsi/ssl_types.h',
+                      'src/core/tsi/transport_security.h',
+                      'src/core/tsi/transport_security_interface.h',
                       'src/core/census/aggregation.h',
-                      'src/core/census/log.h',
+                      'src/core/census/mlog.h',
                       'src/core/census/rpc_metric_id.h',
+                      'third_party/nanopb/pb.h',
+                      'third_party/nanopb/pb_common.h',
+                      'third_party/nanopb/pb_decode.h',
+                      'third_party/nanopb/pb_encode.h',
                       'include/grpc/grpc_security.h',
                       'include/grpc/byte_buffer.h',
                       'include/grpc/byte_buffer_reader.h',
@@ -296,27 +302,6 @@
                       'include/grpc/grpc.h',
                       'include/grpc/status.h',
                       'include/grpc/census.h',
-                      'src/core/httpcli/httpcli_security_connector.c',
-                      'src/core/security/base64.c',
-                      'src/core/security/client_auth_filter.c',
-                      'src/core/security/credentials.c',
-                      'src/core/security/credentials_metadata.c',
-                      'src/core/security/credentials_posix.c',
-                      'src/core/security/credentials_win32.c',
-                      'src/core/security/google_default_credentials.c',
-                      'src/core/security/handshake.c',
-                      'src/core/security/json_token.c',
-                      'src/core/security/jwt_verifier.c',
-                      'src/core/security/secure_endpoint.c',
-                      'src/core/security/security_connector.c',
-                      'src/core/security/security_context.c',
-                      'src/core/security/server_auth_filter.c',
-                      'src/core/security/server_secure_chttp2.c',
-                      'src/core/surface/init_secure.c',
-                      'src/core/surface/secure_channel_create.c',
-                      'src/core/tsi/fake_transport_security.c',
-                      'src/core/tsi/ssl_transport_security.c',
-                      'src/core/tsi/transport_security.c',
                       'src/core/census/grpc_context.c',
                       'src/core/census/grpc_filter.c',
                       'src/core/channel/channel_args.c',
@@ -332,6 +317,7 @@
                       'src/core/client_config/connector.c',
                       'src/core/client_config/default_initial_connect_string.c',
                       'src/core/client_config/initial_connect_string.c',
+                      'src/core/client_config/lb_policies/load_balancer_api.c',
                       'src/core/client_config/lb_policies/pick_first.c',
                       'src/core/client_config/lb_policies/round_robin.c',
                       'src/core/client_config/lb_policy.c',
@@ -346,7 +332,7 @@
                       'src/core/client_config/subchannel_factory.c',
                       'src/core/client_config/subchannel_index.c',
                       'src/core/client_config/uri_parser.c',
-                      'src/core/compression/algorithm.c',
+                      'src/core/compression/compression_algorithm.c',
                       'src/core/compression/message_compress.c',
                       'src/core/debug/trace.c',
                       'src/core/httpcli/format_request.c',
@@ -396,6 +382,7 @@
                       'src/core/json/json_reader.c',
                       'src/core/json/json_string.c',
                       'src/core/json/json_writer.c',
+                      'src/core/proto/grpc/lb/v0/load_balancer.pb.c',
                       'src/core/surface/alarm.c',
                       'src/core/surface/api_trace.c',
                       'src/core/surface/byte_buffer.c',
@@ -445,37 +432,48 @@
                       'src/core/transport/static_metadata.c',
                       'src/core/transport/transport.c',
                       'src/core/transport/transport_op_string.c',
+                      'src/core/httpcli/httpcli_security_connector.c',
+                      'src/core/security/b64.c',
+                      'src/core/security/client_auth_filter.c',
+                      'src/core/security/credentials.c',
+                      'src/core/security/credentials_metadata.c',
+                      'src/core/security/credentials_posix.c',
+                      'src/core/security/credentials_win32.c',
+                      'src/core/security/google_default_credentials.c',
+                      'src/core/security/handshake.c',
+                      'src/core/security/json_token.c',
+                      'src/core/security/jwt_verifier.c',
+                      'src/core/security/secure_endpoint.c',
+                      'src/core/security/security_connector.c',
+                      'src/core/security/security_context.c',
+                      'src/core/security/server_auth_filter.c',
+                      'src/core/security/server_secure_chttp2.c',
+                      'src/core/surface/init_secure.c',
+                      'src/core/surface/secure_channel_create.c',
+                      'src/core/tsi/fake_transport_security.c',
+                      'src/core/tsi/ssl_transport_security.c',
+                      'src/core/tsi/transport_security.c',
                       'src/core/census/context.c',
                       'src/core/census/initialize.c',
-                      'src/core/census/log.c',
+                      'src/core/census/mlog.c',
                       'src/core/census/operation.c',
                       'src/core/census/placeholders.c',
-                      'src/core/census/tracing.c'
+                      'src/core/census/tracing.c',
+                      'third_party/nanopb/pb_common.c',
+                      'third_party/nanopb/pb_decode.c',
+                      'third_party/nanopb/pb_encode.c'
 
     ss.private_header_files = 'src/core/profiling/timers.h',
                               'src/core/support/block_annotate.h',
                               'src/core/support/env.h',
-                              'src/core/support/file.h',
+                              'src/core/support/load_file.h',
                               'src/core/support/murmur_hash.h',
                               'src/core/support/stack_lockfree.h',
                               'src/core/support/string.h',
                               'src/core/support/string_win32.h',
                               'src/core/support/thd_internal.h',
                               'src/core/support/time_precise.h',
-                              'src/core/security/auth_filters.h',
-                              'src/core/security/base64.h',
-                              'src/core/security/credentials.h',
-                              'src/core/security/handshake.h',
-                              'src/core/security/json_token.h',
-                              'src/core/security/jwt_verifier.h',
-                              'src/core/security/secure_endpoint.h',
-                              'src/core/security/security_connector.h',
-                              'src/core/security/security_context.h',
-                              'src/core/tsi/fake_transport_security.h',
-                              'src/core/tsi/ssl_transport_security.h',
-                              'src/core/tsi/ssl_types.h',
-                              'src/core/tsi/transport_security.h',
-                              'src/core/tsi/transport_security_interface.h',
+                              'src/core/support/tmpfile.h',
                               'src/core/census/grpc_filter.h',
                               'src/core/channel/channel_args.h',
                               'src/core/channel/channel_stack.h',
@@ -490,6 +488,7 @@
                               'src/core/client_config/client_config.h',
                               'src/core/client_config/connector.h',
                               'src/core/client_config/initial_connect_string.h',
+                              'src/core/client_config/lb_policies/load_balancer_api.h',
                               'src/core/client_config/lb_policies/pick_first.h',
                               'src/core/client_config/lb_policies/round_robin.h',
                               'src/core/client_config/lb_policy.h',
@@ -540,7 +539,6 @@
                               'src/core/iomgr/time_averaged_stats.h',
                               'src/core/iomgr/timer.h',
                               'src/core/iomgr/timer_heap.h',
-                              'src/core/iomgr/timer_internal.h',
                               'src/core/iomgr/udp_server.h',
                               'src/core/iomgr/wakeup_fd_pipe.h',
                               'src/core/iomgr/wakeup_fd_posix.h',
@@ -551,6 +549,7 @@
                               'src/core/json/json_common.h',
                               'src/core/json/json_reader.h',
                               'src/core/json/json_writer.h',
+                              'src/core/proto/grpc/lb/v0/load_balancer.pb.h',
                               'src/core/statistics/census_interface.h',
                               'src/core/statistics/census_rpc_stats.h',
                               'src/core/surface/api_trace.h',
@@ -590,9 +589,27 @@
                               'src/core/transport/static_metadata.h',
                               'src/core/transport/transport.h',
                               'src/core/transport/transport_impl.h',
+                              'src/core/security/auth_filters.h',
+                              'src/core/security/b64.h',
+                              'src/core/security/credentials.h',
+                              'src/core/security/handshake.h',
+                              'src/core/security/json_token.h',
+                              'src/core/security/jwt_verifier.h',
+                              'src/core/security/secure_endpoint.h',
+                              'src/core/security/security_connector.h',
+                              'src/core/security/security_context.h',
+                              'src/core/tsi/fake_transport_security.h',
+                              'src/core/tsi/ssl_transport_security.h',
+                              'src/core/tsi/ssl_types.h',
+                              'src/core/tsi/transport_security.h',
+                              'src/core/tsi/transport_security_interface.h',
                               'src/core/census/aggregation.h',
-                              'src/core/census/log.h',
-                              'src/core/census/rpc_metric_id.h'
+                              'src/core/census/mlog.h',
+                              'src/core/census/rpc_metric_id.h',
+                              'third_party/nanopb/pb.h',
+                              'third_party/nanopb/pb_common.h',
+                              'third_party/nanopb/pb_decode.h',
+                              'third_party/nanopb/pb_encode.h'
 
     ss.header_mappings_dir = '.'
     # This isn't officially supported in Cocoapods. We've asked for an alternative:
diff --git a/grpc.def b/grpc.def
index bd0bc85..f81aa1b 100644
--- a/grpc.def
+++ b/grpc.def
@@ -182,6 +182,7 @@
     gpr_event_wait
     gpr_ref_init
     gpr_ref
+    gpr_ref_non_zero
     gpr_refn
     gpr_unref
     gpr_stats_init
diff --git a/grpc.gemspec b/grpc.gemspec
index 74b1d68..48ed9d0 100755
--- a/grpc.gemspec
+++ b/grpc.gemspec
@@ -91,13 +91,14 @@
   s.files += %w( src/core/profiling/timers.h )
   s.files += %w( src/core/support/block_annotate.h )
   s.files += %w( src/core/support/env.h )
-  s.files += %w( src/core/support/file.h )
+  s.files += %w( src/core/support/load_file.h )
   s.files += %w( src/core/support/murmur_hash.h )
   s.files += %w( src/core/support/stack_lockfree.h )
   s.files += %w( src/core/support/string.h )
   s.files += %w( src/core/support/string_win32.h )
   s.files += %w( src/core/support/thd_internal.h )
   s.files += %w( src/core/support/time_precise.h )
+  s.files += %w( src/core/support/tmpfile.h )
   s.files += %w( src/core/profiling/basic_timers.c )
   s.files += %w( src/core/profiling/stap_timers.c )
   s.files += %w( src/core/support/alloc.c )
@@ -110,11 +111,9 @@
   s.files += %w( src/core/support/env_linux.c )
   s.files += %w( src/core/support/env_posix.c )
   s.files += %w( src/core/support/env_win32.c )
-  s.files += %w( src/core/support/file.c )
-  s.files += %w( src/core/support/file_posix.c )
-  s.files += %w( src/core/support/file_win32.c )
   s.files += %w( src/core/support/histogram.c )
   s.files += %w( src/core/support/host_port.c )
+  s.files += %w( src/core/support/load_file.c )
   s.files += %w( src/core/support/log.c )
   s.files += %w( src/core/support/log_android.c )
   s.files += %w( src/core/support/log_linux.c )
@@ -140,6 +139,8 @@
   s.files += %w( src/core/support/time_precise.c )
   s.files += %w( src/core/support/time_win32.c )
   s.files += %w( src/core/support/tls_pthread.c )
+  s.files += %w( src/core/support/tmpfile_posix.c )
+  s.files += %w( src/core/support/tmpfile_win32.c )
   s.files += %w( src/core/support/wrap_memcpy.c )
   s.files += %w( include/grpc/grpc_security.h )
   s.files += %w( include/grpc/byte_buffer.h )
@@ -148,20 +149,6 @@
   s.files += %w( include/grpc/grpc.h )
   s.files += %w( include/grpc/status.h )
   s.files += %w( include/grpc/census.h )
-  s.files += %w( src/core/security/auth_filters.h )
-  s.files += %w( src/core/security/base64.h )
-  s.files += %w( src/core/security/credentials.h )
-  s.files += %w( src/core/security/handshake.h )
-  s.files += %w( src/core/security/json_token.h )
-  s.files += %w( src/core/security/jwt_verifier.h )
-  s.files += %w( src/core/security/secure_endpoint.h )
-  s.files += %w( src/core/security/security_connector.h )
-  s.files += %w( src/core/security/security_context.h )
-  s.files += %w( src/core/tsi/fake_transport_security.h )
-  s.files += %w( src/core/tsi/ssl_transport_security.h )
-  s.files += %w( src/core/tsi/ssl_types.h )
-  s.files += %w( src/core/tsi/transport_security.h )
-  s.files += %w( src/core/tsi/transport_security_interface.h )
   s.files += %w( src/core/census/grpc_filter.h )
   s.files += %w( src/core/channel/channel_args.h )
   s.files += %w( src/core/channel/channel_stack.h )
@@ -176,6 +163,7 @@
   s.files += %w( src/core/client_config/client_config.h )
   s.files += %w( src/core/client_config/connector.h )
   s.files += %w( src/core/client_config/initial_connect_string.h )
+  s.files += %w( src/core/client_config/lb_policies/load_balancer_api.h )
   s.files += %w( src/core/client_config/lb_policies/pick_first.h )
   s.files += %w( src/core/client_config/lb_policies/round_robin.h )
   s.files += %w( src/core/client_config/lb_policy.h )
@@ -226,7 +214,6 @@
   s.files += %w( src/core/iomgr/time_averaged_stats.h )
   s.files += %w( src/core/iomgr/timer.h )
   s.files += %w( src/core/iomgr/timer_heap.h )
-  s.files += %w( src/core/iomgr/timer_internal.h )
   s.files += %w( src/core/iomgr/udp_server.h )
   s.files += %w( src/core/iomgr/wakeup_fd_pipe.h )
   s.files += %w( src/core/iomgr/wakeup_fd_posix.h )
@@ -237,6 +224,7 @@
   s.files += %w( src/core/json/json_common.h )
   s.files += %w( src/core/json/json_reader.h )
   s.files += %w( src/core/json/json_writer.h )
+  s.files += %w( src/core/proto/grpc/lb/v0/load_balancer.pb.h )
   s.files += %w( src/core/statistics/census_interface.h )
   s.files += %w( src/core/statistics/census_rpc_stats.h )
   s.files += %w( src/core/surface/api_trace.h )
@@ -276,30 +264,27 @@
   s.files += %w( src/core/transport/static_metadata.h )
   s.files += %w( src/core/transport/transport.h )
   s.files += %w( src/core/transport/transport_impl.h )
+  s.files += %w( src/core/security/auth_filters.h )
+  s.files += %w( src/core/security/b64.h )
+  s.files += %w( src/core/security/credentials.h )
+  s.files += %w( src/core/security/handshake.h )
+  s.files += %w( src/core/security/json_token.h )
+  s.files += %w( src/core/security/jwt_verifier.h )
+  s.files += %w( src/core/security/secure_endpoint.h )
+  s.files += %w( src/core/security/security_connector.h )
+  s.files += %w( src/core/security/security_context.h )
+  s.files += %w( src/core/tsi/fake_transport_security.h )
+  s.files += %w( src/core/tsi/ssl_transport_security.h )
+  s.files += %w( src/core/tsi/ssl_types.h )
+  s.files += %w( src/core/tsi/transport_security.h )
+  s.files += %w( src/core/tsi/transport_security_interface.h )
   s.files += %w( src/core/census/aggregation.h )
-  s.files += %w( src/core/census/log.h )
+  s.files += %w( src/core/census/mlog.h )
   s.files += %w( src/core/census/rpc_metric_id.h )
-  s.files += %w( src/core/httpcli/httpcli_security_connector.c )
-  s.files += %w( src/core/security/base64.c )
-  s.files += %w( src/core/security/client_auth_filter.c )
-  s.files += %w( src/core/security/credentials.c )
-  s.files += %w( src/core/security/credentials_metadata.c )
-  s.files += %w( src/core/security/credentials_posix.c )
-  s.files += %w( src/core/security/credentials_win32.c )
-  s.files += %w( src/core/security/google_default_credentials.c )
-  s.files += %w( src/core/security/handshake.c )
-  s.files += %w( src/core/security/json_token.c )
-  s.files += %w( src/core/security/jwt_verifier.c )
-  s.files += %w( src/core/security/secure_endpoint.c )
-  s.files += %w( src/core/security/security_connector.c )
-  s.files += %w( src/core/security/security_context.c )
-  s.files += %w( src/core/security/server_auth_filter.c )
-  s.files += %w( src/core/security/server_secure_chttp2.c )
-  s.files += %w( src/core/surface/init_secure.c )
-  s.files += %w( src/core/surface/secure_channel_create.c )
-  s.files += %w( src/core/tsi/fake_transport_security.c )
-  s.files += %w( src/core/tsi/ssl_transport_security.c )
-  s.files += %w( src/core/tsi/transport_security.c )
+  s.files += %w( third_party/nanopb/pb.h )
+  s.files += %w( third_party/nanopb/pb_common.h )
+  s.files += %w( third_party/nanopb/pb_decode.h )
+  s.files += %w( third_party/nanopb/pb_encode.h )
   s.files += %w( src/core/census/grpc_context.c )
   s.files += %w( src/core/census/grpc_filter.c )
   s.files += %w( src/core/channel/channel_args.c )
@@ -315,6 +300,7 @@
   s.files += %w( src/core/client_config/connector.c )
   s.files += %w( src/core/client_config/default_initial_connect_string.c )
   s.files += %w( src/core/client_config/initial_connect_string.c )
+  s.files += %w( src/core/client_config/lb_policies/load_balancer_api.c )
   s.files += %w( src/core/client_config/lb_policies/pick_first.c )
   s.files += %w( src/core/client_config/lb_policies/round_robin.c )
   s.files += %w( src/core/client_config/lb_policy.c )
@@ -329,7 +315,7 @@
   s.files += %w( src/core/client_config/subchannel_factory.c )
   s.files += %w( src/core/client_config/subchannel_index.c )
   s.files += %w( src/core/client_config/uri_parser.c )
-  s.files += %w( src/core/compression/algorithm.c )
+  s.files += %w( src/core/compression/compression_algorithm.c )
   s.files += %w( src/core/compression/message_compress.c )
   s.files += %w( src/core/debug/trace.c )
   s.files += %w( src/core/httpcli/format_request.c )
@@ -379,6 +365,7 @@
   s.files += %w( src/core/json/json_reader.c )
   s.files += %w( src/core/json/json_string.c )
   s.files += %w( src/core/json/json_writer.c )
+  s.files += %w( src/core/proto/grpc/lb/v0/load_balancer.pb.c )
   s.files += %w( src/core/surface/alarm.c )
   s.files += %w( src/core/surface/api_trace.c )
   s.files += %w( src/core/surface/byte_buffer.c )
@@ -428,12 +415,36 @@
   s.files += %w( src/core/transport/static_metadata.c )
   s.files += %w( src/core/transport/transport.c )
   s.files += %w( src/core/transport/transport_op_string.c )
+  s.files += %w( src/core/httpcli/httpcli_security_connector.c )
+  s.files += %w( src/core/security/b64.c )
+  s.files += %w( src/core/security/client_auth_filter.c )
+  s.files += %w( src/core/security/credentials.c )
+  s.files += %w( src/core/security/credentials_metadata.c )
+  s.files += %w( src/core/security/credentials_posix.c )
+  s.files += %w( src/core/security/credentials_win32.c )
+  s.files += %w( src/core/security/google_default_credentials.c )
+  s.files += %w( src/core/security/handshake.c )
+  s.files += %w( src/core/security/json_token.c )
+  s.files += %w( src/core/security/jwt_verifier.c )
+  s.files += %w( src/core/security/secure_endpoint.c )
+  s.files += %w( src/core/security/security_connector.c )
+  s.files += %w( src/core/security/security_context.c )
+  s.files += %w( src/core/security/server_auth_filter.c )
+  s.files += %w( src/core/security/server_secure_chttp2.c )
+  s.files += %w( src/core/surface/init_secure.c )
+  s.files += %w( src/core/surface/secure_channel_create.c )
+  s.files += %w( src/core/tsi/fake_transport_security.c )
+  s.files += %w( src/core/tsi/ssl_transport_security.c )
+  s.files += %w( src/core/tsi/transport_security.c )
   s.files += %w( src/core/census/context.c )
   s.files += %w( src/core/census/initialize.c )
-  s.files += %w( src/core/census/log.c )
+  s.files += %w( src/core/census/mlog.c )
   s.files += %w( src/core/census/operation.c )
   s.files += %w( src/core/census/placeholders.c )
   s.files += %w( src/core/census/tracing.c )
+  s.files += %w( third_party/nanopb/pb_common.c )
+  s.files += %w( third_party/nanopb/pb_decode.c )
+  s.files += %w( third_party/nanopb/pb_encode.c )
   s.files += %w( third_party/boringssl/crypto/aes/internal.h )
   s.files += %w( third_party/boringssl/crypto/asn1/asn1_locl.h )
   s.files += %w( third_party/boringssl/crypto/bio/internal.h )
diff --git a/include/grpc++/alarm.h b/include/grpc++/alarm.h
index 9979c34..3b8104d 100644
--- a/include/grpc++/alarm.h
+++ b/include/grpc++/alarm.h
@@ -36,9 +36,12 @@
 #ifndef GRPCXX_ALARM_H
 #define GRPCXX_ALARM_H
 
+#include <grpc++/impl/codegen/completion_queue.h>
 #include <grpc++/impl/codegen/completion_queue_tag.h>
 #include <grpc++/impl/codegen/grpc_library.h>
 #include <grpc++/impl/codegen/time.h>
+#include <grpc++/impl/grpc_library.h>
+#include <grpc/grpc.h>
 
 struct grpc_alarm;
 
@@ -54,14 +57,22 @@
   /// Once the alarm expires (at \a deadline) or it's cancelled (see \a Cancel),
   /// an event with tag \a tag will be added to \a cq. If the alarm expired, the
   /// event's success bit will be true, false otherwise (ie, upon cancellation).
-  Alarm(CompletionQueue* cq, gpr_timespec deadline, void* tag);
+  /// \internal We rely on the presence of \a cq for grpc initialization. If \a
+  /// cq were ever to be removed, a reference to a static
+  /// internal::GrpcLibraryInitializer instance would need to be introduced
+  /// here. \endinternal.
+  template <typename T>
+  Alarm(CompletionQueue* cq, const T& deadline, void* tag)
+      : tag_(tag),
+        alarm_(grpc_alarm_create(cq->cq(), TimePoint<T>(deadline).raw_time(),
+                                 static_cast<void*>(&tag_))) {}
 
   /// Destroy the given completion queue alarm, cancelling it in the process.
-  ~Alarm();
+  ~Alarm() { grpc_alarm_destroy(alarm_); }
 
   /// Cancel a completion queue alarm. Calling this function over an alarm that
   /// has already fired has no effect.
-  void Cancel();
+  void Cancel() { grpc_alarm_cancel(alarm_); }
 
  private:
   class AlarmEntry : public CompletionQueueTag {
diff --git a/include/grpc++/impl/codegen/call.h b/include/grpc++/impl/codegen/call.h
index e65349d..5e450b0 100644
--- a/include/grpc++/impl/codegen/call.h
+++ b/include/grpc++/impl/codegen/call.h
@@ -272,6 +272,7 @@
 class DeserializeFunc {
  public:
   virtual Status Deserialize(grpc_byte_buffer* buf, int max_message_size) = 0;
+  virtual ~DeserializeFunc() {}
 };
 
 template <class R>
@@ -283,6 +284,8 @@
     return SerializationTraits<R>::Deserialize(buf, message_, max_message_size);
   }
 
+  ~DeserializeFuncType() override {}
+
  private:
   R* message_;  // Not a managed pointer because management is external to this
 };
diff --git a/include/grpc++/impl/codegen/proto_utils.h b/include/grpc++/impl/codegen/proto_utils.h
index ce17710..c06fc5d 100644
--- a/include/grpc++/impl/codegen/proto_utils.h
+++ b/include/grpc++/impl/codegen/proto_utils.h
@@ -37,21 +37,50 @@
 #include <type_traits>
 
 #include <grpc/impl/codegen/byte_buffer.h>
+#include <grpc/impl/codegen/log.h>
 #include <grpc++/impl/codegen/serialization_traits.h>
 #include <grpc++/impl/codegen/config_protobuf.h>
 #include <grpc++/impl/codegen/status.h>
 
 namespace grpc {
 
-// Serialize the msg into a buffer created inside the function. The caller
-// should destroy the returned buffer when done with it. If serialization fails,
-// false is returned and buffer is left unchanged.
-Status SerializeProto(const grpc::protobuf::Message& msg,
-                      grpc_byte_buffer** buffer);
+class ProtoSerializerInterface {
+ public:
+  // Serialize the msg into a buffer created inside the function. The caller
+  // should destroy the returned buffer when done with it. If serialization
+  // fails,
+  // false is returned and buffer is left unchanged.
+  virtual Status SerializeProto(const grpc::protobuf::Message& msg,
+                                grpc_byte_buffer** buffer) = 0;
 
-// The caller keeps ownership of buffer and msg.
-Status DeserializeProto(grpc_byte_buffer* buffer, grpc::protobuf::Message* msg,
-                        int max_message_size);
+  // The caller keeps ownership of buffer and msg.
+  virtual Status DeserializeProto(grpc_byte_buffer* buffer,
+                                  grpc::protobuf::Message* msg,
+                                  int max_message_size) = 0;
+};
+
+// TODO(dgq): This is a temporary fix to work around codegen issues. Its purpose
+// is to hold a polymorphic proto serializer/deserializer instance. It's
+// initialized as part of src/cpp/proto/proto_serializer.cc.
+//
+// This global variable plus all related code (ProtoSerializerInteface,
+// ProtoSerializer) will be removed in the future.
+extern ProtoSerializerInterface* g_proto_serializer;
+
+class ProtoSerializer : public ProtoSerializerInterface {
+ public:
+  // Serialize the msg into a buffer created inside the function. The caller
+  // should destroy the returned buffer when done with it. If serialization
+  // fails,
+  // false is returned and buffer is left unchanged.
+  Status SerializeProto(const grpc::protobuf::Message& msg,
+                        grpc_byte_buffer** buffer) override;
+
+  // The caller keeps ownership of buffer and msg.
+  Status DeserializeProto(grpc_byte_buffer* buffer,
+                          grpc::protobuf::Message* msg,
+                          int max_message_size) override;
+};
 
 template <class T>
 class SerializationTraits<T, typename std::enable_if<std::is_base_of<
@@ -60,12 +89,19 @@
   static Status Serialize(const grpc::protobuf::Message& msg,
                           grpc_byte_buffer** buffer, bool* own_buffer) {
     *own_buffer = true;
-    return SerializeProto(msg, buffer);
+    GPR_ASSERT(g_proto_serializer != nullptr &&
+               "No ProtoSerializer instance registered. Make sure grpc++ is "
+               "being initialized.");
+    return g_proto_serializer->SerializeProto(msg, buffer);
   }
   static Status Deserialize(grpc_byte_buffer* buffer,
                             grpc::protobuf::Message* msg,
                             int max_message_size) {
-    auto status = DeserializeProto(buffer, msg, max_message_size);
+    GPR_ASSERT(g_proto_serializer != nullptr &&
+               "No ProtoSerializer instance registered. Make sure grpc++ is "
+               "being initialized.");
+    auto status =
+        g_proto_serializer->DeserializeProto(buffer, msg, max_message_size);
     grpc_byte_buffer_destroy(buffer);
     return status;
   }
diff --git a/include/grpc++/server.h b/include/grpc++/server.h
index 2a71073..c177805 100644
--- a/include/grpc++/server.h
+++ b/include/grpc++/server.h
@@ -79,6 +79,8 @@
   class GlobalCallbacks {
    public:
     virtual ~GlobalCallbacks() {}
+    /// Called before server is created.
+    virtual void UpdateArguments(ChannelArguments* args) {}
     /// Called before application callback for each synchronous server request
     virtual void PreSynchronousRequest(ServerContext* context) = 0;
     /// Called after application callback for each synchronous server request
@@ -108,7 +110,7 @@
   /// \param max_message_size Maximum message length that the channel can
   /// receive.
   Server(ThreadPoolInterface* thread_pool, bool thread_pool_owned,
-         int max_message_size, const ChannelArguments& args);
+         int max_message_size, ChannelArguments* args);
 
   /// Register a service. This call does not take ownership of the service.
   /// The service must exist for the lifetime of the Server instance.
@@ -177,7 +179,7 @@
   bool has_generic_service_;
 
   // Pointer to the c grpc server.
-  grpc_server* const server_;
+  grpc_server* server_;
 
   ThreadPoolInterface* thread_pool_;
   // Whether the thread pool is created and owned by the server.
diff --git a/include/grpc/census.h b/include/grpc/census.h
index dfa3bd7..442a754 100644
--- a/include/grpc/census.h
+++ b/include/grpc/census.h
@@ -80,18 +80,18 @@
   metrics will be recorded. Keys are unique within a context. */
 typedef struct census_context census_context;
 
-/* A tag is a key:value pair. The key is a non-empty, printable (UTF-8
-   encoded), nil-terminated string. The value is a binary string, that may be
-   printable. There are limits on the sizes of both keys and values (see
-   CENSUS_MAX_TAG_KB_LEN definition below), and the number of tags that can be
-   propagated (CENSUS_MAX_PROPAGATED_TAGS). Users should also remember that
-   some systems may have limits on, e.g., the number of bytes that can be
-   transmitted as metadata, and that larger tags means more memory consumed
-   and time in processing. */
+/* A tag is a key:value pair. Both keys and values are nil-terminated strings,
+   containing printable ASCII characters (decimal 32-126). Keys must be at
+   least one character in length. Both keys and values can have at most
+   CENSUS_MAX_TAG_KB_LEN characters (including the terminating nil). The
+   maximum number of tags that can be propagated is
+   CENSUS_MAX_PROPAGATED_TAGS. Users should also remember that some systems
+   may have limits on, e.g., the number of bytes that can be transmitted as
+   metadata, and that larger tags means more memory consumed and time in
+   processing. */
 typedef struct {
   const char *key;
   const char *value;
-  size_t value_len;
   uint8_t flags;
 } census_tag;
 
@@ -103,28 +103,25 @@
 /* Tag flags. */
 #define CENSUS_TAG_PROPAGATE 1 /* Tag should be propagated over RPC */
 #define CENSUS_TAG_STATS 2     /* Tag will be used for statistics aggregation */
-#define CENSUS_TAG_BINARY 4    /* Tag value is not printable */
-#define CENSUS_TAG_RESERVED 8  /* Reserved for internal use. */
-/* Flag values 8,16,32,64,128 are reserved for future/internal use. Clients
+#define CENSUS_TAG_RESERVED 4  /* Reserved for internal use. */
+/* Flag values 4,8,16,32,64,128 are reserved for future/internal use. Clients
    should not use or rely on their values. */
 
 #define CENSUS_TAG_IS_PROPAGATED(flags) (flags & CENSUS_TAG_PROPAGATE)
 #define CENSUS_TAG_IS_STATS(flags) (flags & CENSUS_TAG_STATS)
-#define CENSUS_TAG_IS_BINARY(flags) (flags & CENSUS_TAG_BINARY)
 
 /* An instance of this structure is kept by every context, and records the
    basic information associated with the creation of that context. */
 typedef struct {
-  int n_propagated_tags;        /* number of propagated printable tags */
-  int n_propagated_binary_tags; /* number of propagated binary tags */
-  int n_local_tags;             /* number of non-propagated (local) tags */
-  int n_deleted_tags;           /* number of tags that were deleted */
-  int n_added_tags;             /* number of tags that were added */
-  int n_modified_tags;          /* number of tags that were modified */
-  int n_invalid_tags;           /* number of tags with bad keys or values (e.g.
-                                   longer than CENSUS_MAX_TAG_KV_LEN) */
-  int n_ignored_tags;           /* number of tags ignored because of
-                                   CENSUS_MAX_PROPAGATED_TAGS limit. */
+  int n_propagated_tags; /* number of propagated tags */
+  int n_local_tags;      /* number of non-propagated (local) tags */
+  int n_deleted_tags;    /* number of tags that were deleted */
+  int n_added_tags;      /* number of tags that were added */
+  int n_modified_tags;   /* number of tags that were modified */
+  int n_invalid_tags;    /* number of tags with bad keys or values (e.g.
+                            longer than CENSUS_MAX_TAG_KV_LEN) */
+  int n_ignored_tags;    /* number of tags ignored because of
+                            CENSUS_MAX_PROPAGATED_TAGS limit. */
 } census_context_status;
 
 /* Create a new context, adding and removing tags from an existing context.
@@ -132,10 +129,10 @@
    to add as many tags in a single operation as is practical for the client.
    @param base Base context to build upon. Can be NULL.
    @param tags A set of tags to be added/changed/deleted. Tags with keys that
-   are in 'tags', but not 'base', are added to the tag set. Keys that are in
+   are in 'tags', but not 'base', are added to the context. Keys that are in
    both 'tags' and 'base' will have their value/flags modified. Tags with keys
-   in both, but with NULL or zero-length values, will be deleted from the tag
-   set. Tags with invalid (too long or short) keys or values will be ignored.
+   in both, but with NULL values, will be deleted from the context. Tags with
+   invalid (too long or short) keys or values will be ignored.
    If adding a tag will result in more than CENSUS_MAX_PROPAGATED_TAGS in either
    binary or non-binary tags, they will be ignored, as will deletions of
    tags that don't exist.
@@ -185,32 +182,19 @@
    for use by RPC systems only, for purposes of transmitting/receiving contexts.
    */
 
-/* Encode a context into a buffer. The propagated tags are encoded into the
-   buffer in two regions: one for printable tags, and one for binary tags.
+/* Encode a context into a buffer.
    @param context context to be encoded
-   @param buffer pointer to buffer. This address will be used to encode the
-                 printable tags.
+   @param buffer buffer into which the context will be encoded.
    @param buf_size number of available bytes in buffer.
-   @param print_buf_size Will be set to the number of bytes consumed by
-                         printable tags.
-   @param bin_buf_size Will be set to the number of bytes used to encode the
-                       binary tags.
-   @return A pointer to the binary tag's encoded, or NULL if the buffer was
-           insufficiently large to hold the encoded tags. Thus, if successful,
-           printable tags are encoded into
-           [buffer, buffer + *print_buf_size) and binary tags into
-           [returned-ptr, returned-ptr + *bin_buf_size) (and the returned
-           pointer should be buffer + *print_buf_size) */
-CENSUSAPI char *census_context_encode(const census_context *context,
-                                      char *buffer, size_t buf_size,
-                                      size_t *print_buf_size,
-                                      size_t *bin_buf_size);
+   @return The number of buffer bytes consumed for the encoded context, or
+           zero if the buffer was of insufficient size. */
+CENSUSAPI size_t census_context_encode(const census_context *context,
+                                       char *buffer, size_t buf_size);
 
-/* Decode context buffers encoded with census_context_encode(). Returns NULL
+/* Decode context buffer encoded with census_context_encode(). Returns NULL
    if there is an error in parsing either buffer. */
-CENSUSAPI census_context *census_context_decode(const char *buffer, size_t size,
-                                                const char *bin_buffer,
-                                                size_t bin_size);
+CENSUSAPI census_context *census_context_decode(const char *buffer,
+                                                size_t size);
 
 /* Distributed traces can have a number of options. */
 enum census_trace_mask_values {
diff --git a/include/grpc/impl/codegen/sync.h b/include/grpc/impl/codegen/sync.h
index d2f19d3..6fd7d64 100644
--- a/include/grpc/impl/codegen/sync.h
+++ b/include/grpc/impl/codegen/sync.h
@@ -182,6 +182,10 @@
 /* Increment the reference count *r.  Requires *r initialized. */
 GPRAPI void gpr_ref(gpr_refcount *r);
 
+/* Increment the reference count *r.  Requires *r initialized.
+   Crashes if refcount is zero */
+GPRAPI void gpr_ref_non_zero(gpr_refcount *r);
+
 /* Increment the reference count *r by n.  Requires *r initialized, n > 0. */
 GPRAPI void gpr_refn(gpr_refcount *r, int n);
 
diff --git a/package.json b/package.json
index a704f2b..b2641f7 100644
--- a/package.json
+++ b/package.json
@@ -86,6 +86,451 @@
     "src/node/src/grpc_extension.js",
     "src/node/src/metadata.js",
     "src/node/src/server.js",
+    "include/grpc/grpc_security.h",
+    "include/grpc/byte_buffer.h",
+    "include/grpc/byte_buffer_reader.h",
+    "include/grpc/compression.h",
+    "include/grpc/grpc.h",
+    "include/grpc/status.h",
+    "include/grpc/census.h",
+    "src/core/census/grpc_filter.h",
+    "src/core/channel/channel_args.h",
+    "src/core/channel/channel_stack.h",
+    "src/core/channel/client_channel.h",
+    "src/core/channel/client_uchannel.h",
+    "src/core/channel/compress_filter.h",
+    "src/core/channel/connected_channel.h",
+    "src/core/channel/context.h",
+    "src/core/channel/http_client_filter.h",
+    "src/core/channel/http_server_filter.h",
+    "src/core/channel/subchannel_call_holder.h",
+    "src/core/client_config/client_config.h",
+    "src/core/client_config/connector.h",
+    "src/core/client_config/initial_connect_string.h",
+    "src/core/client_config/lb_policies/load_balancer_api.h",
+    "src/core/client_config/lb_policies/pick_first.h",
+    "src/core/client_config/lb_policies/round_robin.h",
+    "src/core/client_config/lb_policy.h",
+    "src/core/client_config/lb_policy_factory.h",
+    "src/core/client_config/lb_policy_registry.h",
+    "src/core/client_config/resolver.h",
+    "src/core/client_config/resolver_factory.h",
+    "src/core/client_config/resolver_registry.h",
+    "src/core/client_config/resolvers/dns_resolver.h",
+    "src/core/client_config/resolvers/sockaddr_resolver.h",
+    "src/core/client_config/subchannel.h",
+    "src/core/client_config/subchannel_factory.h",
+    "src/core/client_config/subchannel_index.h",
+    "src/core/client_config/uri_parser.h",
+    "src/core/compression/algorithm_metadata.h",
+    "src/core/compression/message_compress.h",
+    "src/core/debug/trace.h",
+    "src/core/httpcli/format_request.h",
+    "src/core/httpcli/httpcli.h",
+    "src/core/httpcli/parser.h",
+    "src/core/iomgr/closure.h",
+    "src/core/iomgr/endpoint.h",
+    "src/core/iomgr/endpoint_pair.h",
+    "src/core/iomgr/exec_ctx.h",
+    "src/core/iomgr/executor.h",
+    "src/core/iomgr/fd_posix.h",
+    "src/core/iomgr/iocp_windows.h",
+    "src/core/iomgr/iomgr.h",
+    "src/core/iomgr/iomgr_internal.h",
+    "src/core/iomgr/iomgr_posix.h",
+    "src/core/iomgr/pollset.h",
+    "src/core/iomgr/pollset_posix.h",
+    "src/core/iomgr/pollset_set.h",
+    "src/core/iomgr/pollset_set_posix.h",
+    "src/core/iomgr/pollset_set_windows.h",
+    "src/core/iomgr/pollset_windows.h",
+    "src/core/iomgr/resolve_address.h",
+    "src/core/iomgr/sockaddr.h",
+    "src/core/iomgr/sockaddr_posix.h",
+    "src/core/iomgr/sockaddr_utils.h",
+    "src/core/iomgr/sockaddr_win32.h",
+    "src/core/iomgr/socket_utils_posix.h",
+    "src/core/iomgr/socket_windows.h",
+    "src/core/iomgr/tcp_client.h",
+    "src/core/iomgr/tcp_posix.h",
+    "src/core/iomgr/tcp_server.h",
+    "src/core/iomgr/tcp_windows.h",
+    "src/core/iomgr/time_averaged_stats.h",
+    "src/core/iomgr/timer.h",
+    "src/core/iomgr/timer_heap.h",
+    "src/core/iomgr/udp_server.h",
+    "src/core/iomgr/wakeup_fd_pipe.h",
+    "src/core/iomgr/wakeup_fd_posix.h",
+    "src/core/iomgr/workqueue.h",
+    "src/core/iomgr/workqueue_posix.h",
+    "src/core/iomgr/workqueue_windows.h",
+    "src/core/json/json.h",
+    "src/core/json/json_common.h",
+    "src/core/json/json_reader.h",
+    "src/core/json/json_writer.h",
+    "src/core/proto/grpc/lb/v0/load_balancer.pb.h",
+    "src/core/statistics/census_interface.h",
+    "src/core/statistics/census_rpc_stats.h",
+    "src/core/surface/api_trace.h",
+    "src/core/surface/call.h",
+    "src/core/surface/call_test_only.h",
+    "src/core/surface/channel.h",
+    "src/core/surface/completion_queue.h",
+    "src/core/surface/event_string.h",
+    "src/core/surface/init.h",
+    "src/core/surface/server.h",
+    "src/core/surface/surface_trace.h",
+    "src/core/transport/byte_stream.h",
+    "src/core/transport/chttp2/alpn.h",
+    "src/core/transport/chttp2/bin_encoder.h",
+    "src/core/transport/chttp2/frame.h",
+    "src/core/transport/chttp2/frame_data.h",
+    "src/core/transport/chttp2/frame_goaway.h",
+    "src/core/transport/chttp2/frame_ping.h",
+    "src/core/transport/chttp2/frame_rst_stream.h",
+    "src/core/transport/chttp2/frame_settings.h",
+    "src/core/transport/chttp2/frame_window_update.h",
+    "src/core/transport/chttp2/hpack_encoder.h",
+    "src/core/transport/chttp2/hpack_parser.h",
+    "src/core/transport/chttp2/hpack_table.h",
+    "src/core/transport/chttp2/http2_errors.h",
+    "src/core/transport/chttp2/huffsyms.h",
+    "src/core/transport/chttp2/incoming_metadata.h",
+    "src/core/transport/chttp2/internal.h",
+    "src/core/transport/chttp2/status_conversion.h",
+    "src/core/transport/chttp2/stream_map.h",
+    "src/core/transport/chttp2/timeout_encoding.h",
+    "src/core/transport/chttp2/varint.h",
+    "src/core/transport/chttp2_transport.h",
+    "src/core/transport/connectivity_state.h",
+    "src/core/transport/metadata.h",
+    "src/core/transport/metadata_batch.h",
+    "src/core/transport/static_metadata.h",
+    "src/core/transport/transport.h",
+    "src/core/transport/transport_impl.h",
+    "src/core/security/auth_filters.h",
+    "src/core/security/b64.h",
+    "src/core/security/credentials.h",
+    "src/core/security/handshake.h",
+    "src/core/security/json_token.h",
+    "src/core/security/jwt_verifier.h",
+    "src/core/security/secure_endpoint.h",
+    "src/core/security/security_connector.h",
+    "src/core/security/security_context.h",
+    "src/core/tsi/fake_transport_security.h",
+    "src/core/tsi/ssl_transport_security.h",
+    "src/core/tsi/ssl_types.h",
+    "src/core/tsi/transport_security.h",
+    "src/core/tsi/transport_security_interface.h",
+    "src/core/census/aggregation.h",
+    "src/core/census/mlog.h",
+    "src/core/census/rpc_metric_id.h",
+    "third_party/nanopb/pb.h",
+    "third_party/nanopb/pb_common.h",
+    "third_party/nanopb/pb_decode.h",
+    "third_party/nanopb/pb_encode.h",
+    "src/core/census/grpc_context.c",
+    "src/core/census/grpc_filter.c",
+    "src/core/channel/channel_args.c",
+    "src/core/channel/channel_stack.c",
+    "src/core/channel/client_channel.c",
+    "src/core/channel/client_uchannel.c",
+    "src/core/channel/compress_filter.c",
+    "src/core/channel/connected_channel.c",
+    "src/core/channel/http_client_filter.c",
+    "src/core/channel/http_server_filter.c",
+    "src/core/channel/subchannel_call_holder.c",
+    "src/core/client_config/client_config.c",
+    "src/core/client_config/connector.c",
+    "src/core/client_config/default_initial_connect_string.c",
+    "src/core/client_config/initial_connect_string.c",
+    "src/core/client_config/lb_policies/load_balancer_api.c",
+    "src/core/client_config/lb_policies/pick_first.c",
+    "src/core/client_config/lb_policies/round_robin.c",
+    "src/core/client_config/lb_policy.c",
+    "src/core/client_config/lb_policy_factory.c",
+    "src/core/client_config/lb_policy_registry.c",
+    "src/core/client_config/resolver.c",
+    "src/core/client_config/resolver_factory.c",
+    "src/core/client_config/resolver_registry.c",
+    "src/core/client_config/resolvers/dns_resolver.c",
+    "src/core/client_config/resolvers/sockaddr_resolver.c",
+    "src/core/client_config/subchannel.c",
+    "src/core/client_config/subchannel_factory.c",
+    "src/core/client_config/subchannel_index.c",
+    "src/core/client_config/uri_parser.c",
+    "src/core/compression/compression_algorithm.c",
+    "src/core/compression/message_compress.c",
+    "src/core/debug/trace.c",
+    "src/core/httpcli/format_request.c",
+    "src/core/httpcli/httpcli.c",
+    "src/core/httpcli/parser.c",
+    "src/core/iomgr/closure.c",
+    "src/core/iomgr/endpoint.c",
+    "src/core/iomgr/endpoint_pair_posix.c",
+    "src/core/iomgr/endpoint_pair_windows.c",
+    "src/core/iomgr/exec_ctx.c",
+    "src/core/iomgr/executor.c",
+    "src/core/iomgr/fd_posix.c",
+    "src/core/iomgr/iocp_windows.c",
+    "src/core/iomgr/iomgr.c",
+    "src/core/iomgr/iomgr_posix.c",
+    "src/core/iomgr/iomgr_windows.c",
+    "src/core/iomgr/pollset_multipoller_with_epoll.c",
+    "src/core/iomgr/pollset_multipoller_with_poll_posix.c",
+    "src/core/iomgr/pollset_posix.c",
+    "src/core/iomgr/pollset_set_posix.c",
+    "src/core/iomgr/pollset_set_windows.c",
+    "src/core/iomgr/pollset_windows.c",
+    "src/core/iomgr/resolve_address_posix.c",
+    "src/core/iomgr/resolve_address_windows.c",
+    "src/core/iomgr/sockaddr_utils.c",
+    "src/core/iomgr/socket_utils_common_posix.c",
+    "src/core/iomgr/socket_utils_linux.c",
+    "src/core/iomgr/socket_utils_posix.c",
+    "src/core/iomgr/socket_windows.c",
+    "src/core/iomgr/tcp_client_posix.c",
+    "src/core/iomgr/tcp_client_windows.c",
+    "src/core/iomgr/tcp_posix.c",
+    "src/core/iomgr/tcp_server_posix.c",
+    "src/core/iomgr/tcp_server_windows.c",
+    "src/core/iomgr/tcp_windows.c",
+    "src/core/iomgr/time_averaged_stats.c",
+    "src/core/iomgr/timer.c",
+    "src/core/iomgr/timer_heap.c",
+    "src/core/iomgr/udp_server.c",
+    "src/core/iomgr/wakeup_fd_eventfd.c",
+    "src/core/iomgr/wakeup_fd_nospecial.c",
+    "src/core/iomgr/wakeup_fd_pipe.c",
+    "src/core/iomgr/wakeup_fd_posix.c",
+    "src/core/iomgr/workqueue_posix.c",
+    "src/core/iomgr/workqueue_windows.c",
+    "src/core/json/json.c",
+    "src/core/json/json_reader.c",
+    "src/core/json/json_string.c",
+    "src/core/json/json_writer.c",
+    "src/core/proto/grpc/lb/v0/load_balancer.pb.c",
+    "src/core/surface/alarm.c",
+    "src/core/surface/api_trace.c",
+    "src/core/surface/byte_buffer.c",
+    "src/core/surface/byte_buffer_reader.c",
+    "src/core/surface/call.c",
+    "src/core/surface/call_details.c",
+    "src/core/surface/call_log_batch.c",
+    "src/core/surface/channel.c",
+    "src/core/surface/channel_connectivity.c",
+    "src/core/surface/channel_create.c",
+    "src/core/surface/channel_ping.c",
+    "src/core/surface/completion_queue.c",
+    "src/core/surface/event_string.c",
+    "src/core/surface/init.c",
+    "src/core/surface/lame_client.c",
+    "src/core/surface/metadata_array.c",
+    "src/core/surface/server.c",
+    "src/core/surface/server_chttp2.c",
+    "src/core/surface/server_create.c",
+    "src/core/surface/validate_metadata.c",
+    "src/core/surface/version.c",
+    "src/core/transport/byte_stream.c",
+    "src/core/transport/chttp2/alpn.c",
+    "src/core/transport/chttp2/bin_encoder.c",
+    "src/core/transport/chttp2/frame_data.c",
+    "src/core/transport/chttp2/frame_goaway.c",
+    "src/core/transport/chttp2/frame_ping.c",
+    "src/core/transport/chttp2/frame_rst_stream.c",
+    "src/core/transport/chttp2/frame_settings.c",
+    "src/core/transport/chttp2/frame_window_update.c",
+    "src/core/transport/chttp2/hpack_encoder.c",
+    "src/core/transport/chttp2/hpack_parser.c",
+    "src/core/transport/chttp2/hpack_table.c",
+    "src/core/transport/chttp2/huffsyms.c",
+    "src/core/transport/chttp2/incoming_metadata.c",
+    "src/core/transport/chttp2/parsing.c",
+    "src/core/transport/chttp2/status_conversion.c",
+    "src/core/transport/chttp2/stream_lists.c",
+    "src/core/transport/chttp2/stream_map.c",
+    "src/core/transport/chttp2/timeout_encoding.c",
+    "src/core/transport/chttp2/varint.c",
+    "src/core/transport/chttp2/writing.c",
+    "src/core/transport/chttp2_transport.c",
+    "src/core/transport/connectivity_state.c",
+    "src/core/transport/metadata.c",
+    "src/core/transport/metadata_batch.c",
+    "src/core/transport/static_metadata.c",
+    "src/core/transport/transport.c",
+    "src/core/transport/transport_op_string.c",
+    "src/core/httpcli/httpcli_security_connector.c",
+    "src/core/security/b64.c",
+    "src/core/security/client_auth_filter.c",
+    "src/core/security/credentials.c",
+    "src/core/security/credentials_metadata.c",
+    "src/core/security/credentials_posix.c",
+    "src/core/security/credentials_win32.c",
+    "src/core/security/google_default_credentials.c",
+    "src/core/security/handshake.c",
+    "src/core/security/json_token.c",
+    "src/core/security/jwt_verifier.c",
+    "src/core/security/secure_endpoint.c",
+    "src/core/security/security_connector.c",
+    "src/core/security/security_context.c",
+    "src/core/security/server_auth_filter.c",
+    "src/core/security/server_secure_chttp2.c",
+    "src/core/surface/init_secure.c",
+    "src/core/surface/secure_channel_create.c",
+    "src/core/tsi/fake_transport_security.c",
+    "src/core/tsi/ssl_transport_security.c",
+    "src/core/tsi/transport_security.c",
+    "src/core/census/context.c",
+    "src/core/census/initialize.c",
+    "src/core/census/mlog.c",
+    "src/core/census/operation.c",
+    "src/core/census/placeholders.c",
+    "src/core/census/tracing.c",
+    "third_party/nanopb/pb_common.c",
+    "third_party/nanopb/pb_decode.c",
+    "third_party/nanopb/pb_encode.c",
+    "include/grpc/impl/codegen/byte_buffer.h",
+    "include/grpc/impl/codegen/compression_types.h",
+    "include/grpc/impl/codegen/connectivity_state.h",
+    "include/grpc/impl/codegen/grpc_types.h",
+    "include/grpc/impl/codegen/propagation_bits.h",
+    "include/grpc/impl/codegen/status.h",
+    "include/grpc/impl/codegen/alloc.h",
+    "include/grpc/impl/codegen/atm.h",
+    "include/grpc/impl/codegen/atm_gcc_atomic.h",
+    "include/grpc/impl/codegen/atm_gcc_sync.h",
+    "include/grpc/impl/codegen/atm_win32.h",
+    "include/grpc/impl/codegen/log.h",
+    "include/grpc/impl/codegen/port_platform.h",
+    "include/grpc/impl/codegen/slice.h",
+    "include/grpc/impl/codegen/slice_buffer.h",
+    "include/grpc/impl/codegen/sync.h",
+    "include/grpc/impl/codegen/sync_generic.h",
+    "include/grpc/impl/codegen/sync_posix.h",
+    "include/grpc/impl/codegen/sync_win32.h",
+    "include/grpc/impl/codegen/time.h",
+    "third_party/zlib/crc32.h",
+    "third_party/zlib/deflate.h",
+    "third_party/zlib/gzguts.h",
+    "third_party/zlib/inffast.h",
+    "third_party/zlib/inffixed.h",
+    "third_party/zlib/inflate.h",
+    "third_party/zlib/inftrees.h",
+    "third_party/zlib/trees.h",
+    "third_party/zlib/zconf.h",
+    "third_party/zlib/zlib.h",
+    "third_party/zlib/zutil.h",
+    "third_party/zlib/adler32.c",
+    "third_party/zlib/compress.c",
+    "third_party/zlib/crc32.c",
+    "third_party/zlib/deflate.c",
+    "third_party/zlib/gzclose.c",
+    "third_party/zlib/gzlib.c",
+    "third_party/zlib/gzread.c",
+    "third_party/zlib/gzwrite.c",
+    "third_party/zlib/infback.c",
+    "third_party/zlib/inffast.c",
+    "third_party/zlib/inflate.c",
+    "third_party/zlib/inftrees.c",
+    "third_party/zlib/trees.c",
+    "third_party/zlib/uncompr.c",
+    "third_party/zlib/zutil.c",
+    "include/grpc/support/alloc.h",
+    "include/grpc/support/atm.h",
+    "include/grpc/support/atm_gcc_atomic.h",
+    "include/grpc/support/atm_gcc_sync.h",
+    "include/grpc/support/atm_win32.h",
+    "include/grpc/support/avl.h",
+    "include/grpc/support/cmdline.h",
+    "include/grpc/support/cpu.h",
+    "include/grpc/support/histogram.h",
+    "include/grpc/support/host_port.h",
+    "include/grpc/support/log.h",
+    "include/grpc/support/log_win32.h",
+    "include/grpc/support/port_platform.h",
+    "include/grpc/support/slice.h",
+    "include/grpc/support/slice_buffer.h",
+    "include/grpc/support/string_util.h",
+    "include/grpc/support/subprocess.h",
+    "include/grpc/support/sync.h",
+    "include/grpc/support/sync_generic.h",
+    "include/grpc/support/sync_posix.h",
+    "include/grpc/support/sync_win32.h",
+    "include/grpc/support/thd.h",
+    "include/grpc/support/time.h",
+    "include/grpc/support/tls.h",
+    "include/grpc/support/tls_gcc.h",
+    "include/grpc/support/tls_msvc.h",
+    "include/grpc/support/tls_pthread.h",
+    "include/grpc/support/useful.h",
+    "include/grpc/impl/codegen/alloc.h",
+    "include/grpc/impl/codegen/atm.h",
+    "include/grpc/impl/codegen/atm_gcc_atomic.h",
+    "include/grpc/impl/codegen/atm_gcc_sync.h",
+    "include/grpc/impl/codegen/atm_win32.h",
+    "include/grpc/impl/codegen/log.h",
+    "include/grpc/impl/codegen/port_platform.h",
+    "include/grpc/impl/codegen/slice.h",
+    "include/grpc/impl/codegen/slice_buffer.h",
+    "include/grpc/impl/codegen/sync.h",
+    "include/grpc/impl/codegen/sync_generic.h",
+    "include/grpc/impl/codegen/sync_posix.h",
+    "include/grpc/impl/codegen/sync_win32.h",
+    "include/grpc/impl/codegen/time.h",
+    "src/core/profiling/timers.h",
+    "src/core/support/block_annotate.h",
+    "src/core/support/env.h",
+    "src/core/support/load_file.h",
+    "src/core/support/murmur_hash.h",
+    "src/core/support/stack_lockfree.h",
+    "src/core/support/string.h",
+    "src/core/support/string_win32.h",
+    "src/core/support/thd_internal.h",
+    "src/core/support/time_precise.h",
+    "src/core/support/tmpfile.h",
+    "src/core/profiling/basic_timers.c",
+    "src/core/profiling/stap_timers.c",
+    "src/core/support/alloc.c",
+    "src/core/support/avl.c",
+    "src/core/support/cmdline.c",
+    "src/core/support/cpu_iphone.c",
+    "src/core/support/cpu_linux.c",
+    "src/core/support/cpu_posix.c",
+    "src/core/support/cpu_windows.c",
+    "src/core/support/env_linux.c",
+    "src/core/support/env_posix.c",
+    "src/core/support/env_win32.c",
+    "src/core/support/histogram.c",
+    "src/core/support/host_port.c",
+    "src/core/support/load_file.c",
+    "src/core/support/log.c",
+    "src/core/support/log_android.c",
+    "src/core/support/log_linux.c",
+    "src/core/support/log_posix.c",
+    "src/core/support/log_win32.c",
+    "src/core/support/murmur_hash.c",
+    "src/core/support/slice.c",
+    "src/core/support/slice_buffer.c",
+    "src/core/support/stack_lockfree.c",
+    "src/core/support/string.c",
+    "src/core/support/string_posix.c",
+    "src/core/support/string_win32.c",
+    "src/core/support/subprocess_posix.c",
+    "src/core/support/subprocess_windows.c",
+    "src/core/support/sync.c",
+    "src/core/support/sync_posix.c",
+    "src/core/support/sync_win32.c",
+    "src/core/support/thd.c",
+    "src/core/support/thd_posix.c",
+    "src/core/support/thd_win32.c",
+    "src/core/support/time.c",
+    "src/core/support/time_posix.c",
+    "src/core/support/time_precise.c",
+    "src/core/support/time_win32.c",
+    "src/core/support/tls_pthread.c",
+    "src/core/support/tmpfile_posix.c",
+    "src/core/support/tmpfile_win32.c",
+    "src/core/support/wrap_memcpy.c",
     "third_party/boringssl/crypto/aes/internal.h",
     "third_party/boringssl/crypto/asn1/asn1_locl.h",
     "third_party/boringssl/crypto/bio/internal.h",
@@ -487,440 +932,6 @@
     "third_party/boringssl/ssl/t1_enc.c",
     "third_party/boringssl/ssl/t1_lib.c",
     "third_party/boringssl/ssl/tls_record.c",
-    "include/grpc/grpc_security.h",
-    "include/grpc/byte_buffer.h",
-    "include/grpc/byte_buffer_reader.h",
-    "include/grpc/compression.h",
-    "include/grpc/grpc.h",
-    "include/grpc/status.h",
-    "include/grpc/census.h",
-    "src/core/security/auth_filters.h",
-    "src/core/security/base64.h",
-    "src/core/security/credentials.h",
-    "src/core/security/handshake.h",
-    "src/core/security/json_token.h",
-    "src/core/security/jwt_verifier.h",
-    "src/core/security/secure_endpoint.h",
-    "src/core/security/security_connector.h",
-    "src/core/security/security_context.h",
-    "src/core/tsi/fake_transport_security.h",
-    "src/core/tsi/ssl_transport_security.h",
-    "src/core/tsi/ssl_types.h",
-    "src/core/tsi/transport_security.h",
-    "src/core/tsi/transport_security_interface.h",
-    "src/core/census/grpc_filter.h",
-    "src/core/channel/channel_args.h",
-    "src/core/channel/channel_stack.h",
-    "src/core/channel/client_channel.h",
-    "src/core/channel/client_uchannel.h",
-    "src/core/channel/compress_filter.h",
-    "src/core/channel/connected_channel.h",
-    "src/core/channel/context.h",
-    "src/core/channel/http_client_filter.h",
-    "src/core/channel/http_server_filter.h",
-    "src/core/channel/subchannel_call_holder.h",
-    "src/core/client_config/client_config.h",
-    "src/core/client_config/connector.h",
-    "src/core/client_config/initial_connect_string.h",
-    "src/core/client_config/lb_policies/pick_first.h",
-    "src/core/client_config/lb_policies/round_robin.h",
-    "src/core/client_config/lb_policy.h",
-    "src/core/client_config/lb_policy_factory.h",
-    "src/core/client_config/lb_policy_registry.h",
-    "src/core/client_config/resolver.h",
-    "src/core/client_config/resolver_factory.h",
-    "src/core/client_config/resolver_registry.h",
-    "src/core/client_config/resolvers/dns_resolver.h",
-    "src/core/client_config/resolvers/sockaddr_resolver.h",
-    "src/core/client_config/subchannel.h",
-    "src/core/client_config/subchannel_factory.h",
-    "src/core/client_config/subchannel_index.h",
-    "src/core/client_config/uri_parser.h",
-    "src/core/compression/algorithm_metadata.h",
-    "src/core/compression/message_compress.h",
-    "src/core/debug/trace.h",
-    "src/core/httpcli/format_request.h",
-    "src/core/httpcli/httpcli.h",
-    "src/core/httpcli/parser.h",
-    "src/core/iomgr/closure.h",
-    "src/core/iomgr/endpoint.h",
-    "src/core/iomgr/endpoint_pair.h",
-    "src/core/iomgr/exec_ctx.h",
-    "src/core/iomgr/executor.h",
-    "src/core/iomgr/fd_posix.h",
-    "src/core/iomgr/iocp_windows.h",
-    "src/core/iomgr/iomgr.h",
-    "src/core/iomgr/iomgr_internal.h",
-    "src/core/iomgr/iomgr_posix.h",
-    "src/core/iomgr/pollset.h",
-    "src/core/iomgr/pollset_posix.h",
-    "src/core/iomgr/pollset_set.h",
-    "src/core/iomgr/pollset_set_posix.h",
-    "src/core/iomgr/pollset_set_windows.h",
-    "src/core/iomgr/pollset_windows.h",
-    "src/core/iomgr/resolve_address.h",
-    "src/core/iomgr/sockaddr.h",
-    "src/core/iomgr/sockaddr_posix.h",
-    "src/core/iomgr/sockaddr_utils.h",
-    "src/core/iomgr/sockaddr_win32.h",
-    "src/core/iomgr/socket_utils_posix.h",
-    "src/core/iomgr/socket_windows.h",
-    "src/core/iomgr/tcp_client.h",
-    "src/core/iomgr/tcp_posix.h",
-    "src/core/iomgr/tcp_server.h",
-    "src/core/iomgr/tcp_windows.h",
-    "src/core/iomgr/time_averaged_stats.h",
-    "src/core/iomgr/timer.h",
-    "src/core/iomgr/timer_heap.h",
-    "src/core/iomgr/timer_internal.h",
-    "src/core/iomgr/udp_server.h",
-    "src/core/iomgr/wakeup_fd_pipe.h",
-    "src/core/iomgr/wakeup_fd_posix.h",
-    "src/core/iomgr/workqueue.h",
-    "src/core/iomgr/workqueue_posix.h",
-    "src/core/iomgr/workqueue_windows.h",
-    "src/core/json/json.h",
-    "src/core/json/json_common.h",
-    "src/core/json/json_reader.h",
-    "src/core/json/json_writer.h",
-    "src/core/statistics/census_interface.h",
-    "src/core/statistics/census_rpc_stats.h",
-    "src/core/surface/api_trace.h",
-    "src/core/surface/call.h",
-    "src/core/surface/call_test_only.h",
-    "src/core/surface/channel.h",
-    "src/core/surface/completion_queue.h",
-    "src/core/surface/event_string.h",
-    "src/core/surface/init.h",
-    "src/core/surface/server.h",
-    "src/core/surface/surface_trace.h",
-    "src/core/transport/byte_stream.h",
-    "src/core/transport/chttp2/alpn.h",
-    "src/core/transport/chttp2/bin_encoder.h",
-    "src/core/transport/chttp2/frame.h",
-    "src/core/transport/chttp2/frame_data.h",
-    "src/core/transport/chttp2/frame_goaway.h",
-    "src/core/transport/chttp2/frame_ping.h",
-    "src/core/transport/chttp2/frame_rst_stream.h",
-    "src/core/transport/chttp2/frame_settings.h",
-    "src/core/transport/chttp2/frame_window_update.h",
-    "src/core/transport/chttp2/hpack_encoder.h",
-    "src/core/transport/chttp2/hpack_parser.h",
-    "src/core/transport/chttp2/hpack_table.h",
-    "src/core/transport/chttp2/http2_errors.h",
-    "src/core/transport/chttp2/huffsyms.h",
-    "src/core/transport/chttp2/incoming_metadata.h",
-    "src/core/transport/chttp2/internal.h",
-    "src/core/transport/chttp2/status_conversion.h",
-    "src/core/transport/chttp2/stream_map.h",
-    "src/core/transport/chttp2/timeout_encoding.h",
-    "src/core/transport/chttp2/varint.h",
-    "src/core/transport/chttp2_transport.h",
-    "src/core/transport/connectivity_state.h",
-    "src/core/transport/metadata.h",
-    "src/core/transport/metadata_batch.h",
-    "src/core/transport/static_metadata.h",
-    "src/core/transport/transport.h",
-    "src/core/transport/transport_impl.h",
-    "src/core/census/aggregation.h",
-    "src/core/census/log.h",
-    "src/core/census/rpc_metric_id.h",
-    "src/core/httpcli/httpcli_security_connector.c",
-    "src/core/security/base64.c",
-    "src/core/security/client_auth_filter.c",
-    "src/core/security/credentials.c",
-    "src/core/security/credentials_metadata.c",
-    "src/core/security/credentials_posix.c",
-    "src/core/security/credentials_win32.c",
-    "src/core/security/google_default_credentials.c",
-    "src/core/security/handshake.c",
-    "src/core/security/json_token.c",
-    "src/core/security/jwt_verifier.c",
-    "src/core/security/secure_endpoint.c",
-    "src/core/security/security_connector.c",
-    "src/core/security/security_context.c",
-    "src/core/security/server_auth_filter.c",
-    "src/core/security/server_secure_chttp2.c",
-    "src/core/surface/init_secure.c",
-    "src/core/surface/secure_channel_create.c",
-    "src/core/tsi/fake_transport_security.c",
-    "src/core/tsi/ssl_transport_security.c",
-    "src/core/tsi/transport_security.c",
-    "src/core/census/grpc_context.c",
-    "src/core/census/grpc_filter.c",
-    "src/core/channel/channel_args.c",
-    "src/core/channel/channel_stack.c",
-    "src/core/channel/client_channel.c",
-    "src/core/channel/client_uchannel.c",
-    "src/core/channel/compress_filter.c",
-    "src/core/channel/connected_channel.c",
-    "src/core/channel/http_client_filter.c",
-    "src/core/channel/http_server_filter.c",
-    "src/core/channel/subchannel_call_holder.c",
-    "src/core/client_config/client_config.c",
-    "src/core/client_config/connector.c",
-    "src/core/client_config/default_initial_connect_string.c",
-    "src/core/client_config/initial_connect_string.c",
-    "src/core/client_config/lb_policies/pick_first.c",
-    "src/core/client_config/lb_policies/round_robin.c",
-    "src/core/client_config/lb_policy.c",
-    "src/core/client_config/lb_policy_factory.c",
-    "src/core/client_config/lb_policy_registry.c",
-    "src/core/client_config/resolver.c",
-    "src/core/client_config/resolver_factory.c",
-    "src/core/client_config/resolver_registry.c",
-    "src/core/client_config/resolvers/dns_resolver.c",
-    "src/core/client_config/resolvers/sockaddr_resolver.c",
-    "src/core/client_config/subchannel.c",
-    "src/core/client_config/subchannel_factory.c",
-    "src/core/client_config/subchannel_index.c",
-    "src/core/client_config/uri_parser.c",
-    "src/core/compression/algorithm.c",
-    "src/core/compression/message_compress.c",
-    "src/core/debug/trace.c",
-    "src/core/httpcli/format_request.c",
-    "src/core/httpcli/httpcli.c",
-    "src/core/httpcli/parser.c",
-    "src/core/iomgr/closure.c",
-    "src/core/iomgr/endpoint.c",
-    "src/core/iomgr/endpoint_pair_posix.c",
-    "src/core/iomgr/endpoint_pair_windows.c",
-    "src/core/iomgr/exec_ctx.c",
-    "src/core/iomgr/executor.c",
-    "src/core/iomgr/fd_posix.c",
-    "src/core/iomgr/iocp_windows.c",
-    "src/core/iomgr/iomgr.c",
-    "src/core/iomgr/iomgr_posix.c",
-    "src/core/iomgr/iomgr_windows.c",
-    "src/core/iomgr/pollset_multipoller_with_epoll.c",
-    "src/core/iomgr/pollset_multipoller_with_poll_posix.c",
-    "src/core/iomgr/pollset_posix.c",
-    "src/core/iomgr/pollset_set_posix.c",
-    "src/core/iomgr/pollset_set_windows.c",
-    "src/core/iomgr/pollset_windows.c",
-    "src/core/iomgr/resolve_address_posix.c",
-    "src/core/iomgr/resolve_address_windows.c",
-    "src/core/iomgr/sockaddr_utils.c",
-    "src/core/iomgr/socket_utils_common_posix.c",
-    "src/core/iomgr/socket_utils_linux.c",
-    "src/core/iomgr/socket_utils_posix.c",
-    "src/core/iomgr/socket_windows.c",
-    "src/core/iomgr/tcp_client_posix.c",
-    "src/core/iomgr/tcp_client_windows.c",
-    "src/core/iomgr/tcp_posix.c",
-    "src/core/iomgr/tcp_server_posix.c",
-    "src/core/iomgr/tcp_server_windows.c",
-    "src/core/iomgr/tcp_windows.c",
-    "src/core/iomgr/time_averaged_stats.c",
-    "src/core/iomgr/timer.c",
-    "src/core/iomgr/timer_heap.c",
-    "src/core/iomgr/udp_server.c",
-    "src/core/iomgr/wakeup_fd_eventfd.c",
-    "src/core/iomgr/wakeup_fd_nospecial.c",
-    "src/core/iomgr/wakeup_fd_pipe.c",
-    "src/core/iomgr/wakeup_fd_posix.c",
-    "src/core/iomgr/workqueue_posix.c",
-    "src/core/iomgr/workqueue_windows.c",
-    "src/core/json/json.c",
-    "src/core/json/json_reader.c",
-    "src/core/json/json_string.c",
-    "src/core/json/json_writer.c",
-    "src/core/surface/alarm.c",
-    "src/core/surface/api_trace.c",
-    "src/core/surface/byte_buffer.c",
-    "src/core/surface/byte_buffer_reader.c",
-    "src/core/surface/call.c",
-    "src/core/surface/call_details.c",
-    "src/core/surface/call_log_batch.c",
-    "src/core/surface/channel.c",
-    "src/core/surface/channel_connectivity.c",
-    "src/core/surface/channel_create.c",
-    "src/core/surface/channel_ping.c",
-    "src/core/surface/completion_queue.c",
-    "src/core/surface/event_string.c",
-    "src/core/surface/init.c",
-    "src/core/surface/lame_client.c",
-    "src/core/surface/metadata_array.c",
-    "src/core/surface/server.c",
-    "src/core/surface/server_chttp2.c",
-    "src/core/surface/server_create.c",
-    "src/core/surface/validate_metadata.c",
-    "src/core/surface/version.c",
-    "src/core/transport/byte_stream.c",
-    "src/core/transport/chttp2/alpn.c",
-    "src/core/transport/chttp2/bin_encoder.c",
-    "src/core/transport/chttp2/frame_data.c",
-    "src/core/transport/chttp2/frame_goaway.c",
-    "src/core/transport/chttp2/frame_ping.c",
-    "src/core/transport/chttp2/frame_rst_stream.c",
-    "src/core/transport/chttp2/frame_settings.c",
-    "src/core/transport/chttp2/frame_window_update.c",
-    "src/core/transport/chttp2/hpack_encoder.c",
-    "src/core/transport/chttp2/hpack_parser.c",
-    "src/core/transport/chttp2/hpack_table.c",
-    "src/core/transport/chttp2/huffsyms.c",
-    "src/core/transport/chttp2/incoming_metadata.c",
-    "src/core/transport/chttp2/parsing.c",
-    "src/core/transport/chttp2/status_conversion.c",
-    "src/core/transport/chttp2/stream_lists.c",
-    "src/core/transport/chttp2/stream_map.c",
-    "src/core/transport/chttp2/timeout_encoding.c",
-    "src/core/transport/chttp2/varint.c",
-    "src/core/transport/chttp2/writing.c",
-    "src/core/transport/chttp2_transport.c",
-    "src/core/transport/connectivity_state.c",
-    "src/core/transport/metadata.c",
-    "src/core/transport/metadata_batch.c",
-    "src/core/transport/static_metadata.c",
-    "src/core/transport/transport.c",
-    "src/core/transport/transport_op_string.c",
-    "src/core/census/context.c",
-    "src/core/census/initialize.c",
-    "src/core/census/log.c",
-    "src/core/census/operation.c",
-    "src/core/census/placeholders.c",
-    "src/core/census/tracing.c",
-    "include/grpc/impl/codegen/byte_buffer.h",
-    "include/grpc/impl/codegen/compression_types.h",
-    "include/grpc/impl/codegen/connectivity_state.h",
-    "include/grpc/impl/codegen/grpc_types.h",
-    "include/grpc/impl/codegen/propagation_bits.h",
-    "include/grpc/impl/codegen/status.h",
-    "include/grpc/impl/codegen/alloc.h",
-    "include/grpc/impl/codegen/atm.h",
-    "include/grpc/impl/codegen/atm_gcc_atomic.h",
-    "include/grpc/impl/codegen/atm_gcc_sync.h",
-    "include/grpc/impl/codegen/atm_win32.h",
-    "include/grpc/impl/codegen/log.h",
-    "include/grpc/impl/codegen/port_platform.h",
-    "include/grpc/impl/codegen/slice.h",
-    "include/grpc/impl/codegen/slice_buffer.h",
-    "include/grpc/impl/codegen/sync.h",
-    "include/grpc/impl/codegen/sync_generic.h",
-    "include/grpc/impl/codegen/sync_posix.h",
-    "include/grpc/impl/codegen/sync_win32.h",
-    "include/grpc/impl/codegen/time.h",
-    "third_party/zlib/crc32.h",
-    "third_party/zlib/deflate.h",
-    "third_party/zlib/gzguts.h",
-    "third_party/zlib/inffast.h",
-    "third_party/zlib/inffixed.h",
-    "third_party/zlib/inflate.h",
-    "third_party/zlib/inftrees.h",
-    "third_party/zlib/trees.h",
-    "third_party/zlib/zconf.h",
-    "third_party/zlib/zlib.h",
-    "third_party/zlib/zutil.h",
-    "third_party/zlib/adler32.c",
-    "third_party/zlib/compress.c",
-    "third_party/zlib/crc32.c",
-    "third_party/zlib/deflate.c",
-    "third_party/zlib/gzclose.c",
-    "third_party/zlib/gzlib.c",
-    "third_party/zlib/gzread.c",
-    "third_party/zlib/gzwrite.c",
-    "third_party/zlib/infback.c",
-    "third_party/zlib/inffast.c",
-    "third_party/zlib/inflate.c",
-    "third_party/zlib/inftrees.c",
-    "third_party/zlib/trees.c",
-    "third_party/zlib/uncompr.c",
-    "third_party/zlib/zutil.c",
-    "include/grpc/support/alloc.h",
-    "include/grpc/support/atm.h",
-    "include/grpc/support/atm_gcc_atomic.h",
-    "include/grpc/support/atm_gcc_sync.h",
-    "include/grpc/support/atm_win32.h",
-    "include/grpc/support/avl.h",
-    "include/grpc/support/cmdline.h",
-    "include/grpc/support/cpu.h",
-    "include/grpc/support/histogram.h",
-    "include/grpc/support/host_port.h",
-    "include/grpc/support/log.h",
-    "include/grpc/support/log_win32.h",
-    "include/grpc/support/port_platform.h",
-    "include/grpc/support/slice.h",
-    "include/grpc/support/slice_buffer.h",
-    "include/grpc/support/string_util.h",
-    "include/grpc/support/subprocess.h",
-    "include/grpc/support/sync.h",
-    "include/grpc/support/sync_generic.h",
-    "include/grpc/support/sync_posix.h",
-    "include/grpc/support/sync_win32.h",
-    "include/grpc/support/thd.h",
-    "include/grpc/support/time.h",
-    "include/grpc/support/tls.h",
-    "include/grpc/support/tls_gcc.h",
-    "include/grpc/support/tls_msvc.h",
-    "include/grpc/support/tls_pthread.h",
-    "include/grpc/support/useful.h",
-    "include/grpc/impl/codegen/alloc.h",
-    "include/grpc/impl/codegen/atm.h",
-    "include/grpc/impl/codegen/atm_gcc_atomic.h",
-    "include/grpc/impl/codegen/atm_gcc_sync.h",
-    "include/grpc/impl/codegen/atm_win32.h",
-    "include/grpc/impl/codegen/log.h",
-    "include/grpc/impl/codegen/port_platform.h",
-    "include/grpc/impl/codegen/slice.h",
-    "include/grpc/impl/codegen/slice_buffer.h",
-    "include/grpc/impl/codegen/sync.h",
-    "include/grpc/impl/codegen/sync_generic.h",
-    "include/grpc/impl/codegen/sync_posix.h",
-    "include/grpc/impl/codegen/sync_win32.h",
-    "include/grpc/impl/codegen/time.h",
-    "src/core/profiling/timers.h",
-    "src/core/support/block_annotate.h",
-    "src/core/support/env.h",
-    "src/core/support/file.h",
-    "src/core/support/murmur_hash.h",
-    "src/core/support/stack_lockfree.h",
-    "src/core/support/string.h",
-    "src/core/support/string_win32.h",
-    "src/core/support/thd_internal.h",
-    "src/core/support/time_precise.h",
-    "src/core/profiling/basic_timers.c",
-    "src/core/profiling/stap_timers.c",
-    "src/core/support/alloc.c",
-    "src/core/support/avl.c",
-    "src/core/support/cmdline.c",
-    "src/core/support/cpu_iphone.c",
-    "src/core/support/cpu_linux.c",
-    "src/core/support/cpu_posix.c",
-    "src/core/support/cpu_windows.c",
-    "src/core/support/env_linux.c",
-    "src/core/support/env_posix.c",
-    "src/core/support/env_win32.c",
-    "src/core/support/file.c",
-    "src/core/support/file_posix.c",
-    "src/core/support/file_win32.c",
-    "src/core/support/histogram.c",
-    "src/core/support/host_port.c",
-    "src/core/support/log.c",
-    "src/core/support/log_android.c",
-    "src/core/support/log_linux.c",
-    "src/core/support/log_posix.c",
-    "src/core/support/log_win32.c",
-    "src/core/support/murmur_hash.c",
-    "src/core/support/slice.c",
-    "src/core/support/slice_buffer.c",
-    "src/core/support/stack_lockfree.c",
-    "src/core/support/string.c",
-    "src/core/support/string_posix.c",
-    "src/core/support/string_win32.c",
-    "src/core/support/subprocess_posix.c",
-    "src/core/support/subprocess_windows.c",
-    "src/core/support/sync.c",
-    "src/core/support/sync_posix.c",
-    "src/core/support/sync_win32.c",
-    "src/core/support/thd.c",
-    "src/core/support/thd_posix.c",
-    "src/core/support/thd_win32.c",
-    "src/core/support/time.c",
-    "src/core/support/time_posix.c",
-    "src/core/support/time_precise.c",
-    "src/core/support/time_win32.c",
-    "src/core/support/tls_pthread.c",
-    "src/core/support/wrap_memcpy.c",
     "binding.gyp"
   ],
   "main": "src/node/index.js",
diff --git a/package.xml b/package.xml
new file mode 100644
index 0000000..ae2793a
--- /dev/null
+++ b/package.xml
@@ -0,0 +1,982 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<package packagerversion="1.9.5" version="2.0" xmlns="http://pear.php.net/dtd/package-2.0" xmlns:tasks="http://pear.php.net/dtd/tasks-1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://pear.php.net/dtd/tasks-1.0 http://pear.php.net/dtd/tasks-1.0.xsd http://pear.php.net/dtd/package-2.0 http://pear.php.net/dtd/package-2.0.xsd">
+ <name>grpc</name>
+ <channel>pecl.php.net</channel>
+ <summary>A high performance, open source, general RPC framework that puts mobile and HTTP/2 first.</summary>
+ <description>Remote Procedure Calls (RPCs) provide a useful abstraction for building distributed applications and services. The libraries in this repository provide a concrete implementation of the gRPC protocol, layered over HTTP/2. These libraries enable communication between clients and servers using any combination of the supported languages.</description>
+ <lead>
+  <name>Stanley Cheung</name>
+  <user>stanleycheung</user>
+  <email>grpc-packages@google.com</email>
+  <active>yes</active>
+ </lead>
+ <date>2016-03-01</date>
+ <time>16:06:07</time>
+ <version>
+  <release>0.14.0</release>
+  <api>0.14.0</api>
+ </version>
+ <stability>
+  <release>beta</release>
+  <api>beta</api>
+ </stability>
+ <license>BSD</license>
+ <notes>
+- Increase unit test code coverage #5225
+ </notes>
+ <contents>
+  <dir baseinstalldir="/" name="/">
+    <file baseinstalldir="/" name="config.m4" role="src" />
+    <file baseinstalldir="/" name="src/php/ext/grpc/CREDITS" role="src" />
+    <file baseinstalldir="/" name="src/php/ext/grpc/LICENSE" role="src" />
+    <file baseinstalldir="/" name="src/php/ext/grpc/README.md" role="src" />
+    <file baseinstalldir="/" name="src/php/ext/grpc/byte_buffer.c" role="src" />
+    <file baseinstalldir="/" name="src/php/ext/grpc/call.c" role="src" />
+    <file baseinstalldir="/" name="src/php/ext/grpc/call_credentials.c" role="src" />
+    <file baseinstalldir="/" name="src/php/ext/grpc/channel.c" role="src" />
+    <file baseinstalldir="/" name="src/php/ext/grpc/channel_credentials.c" role="src" />
+    <file baseinstalldir="/" name="src/php/ext/grpc/completion_queue.c" role="src" />
+    <file baseinstalldir="/" name="src/php/ext/grpc/php_grpc.c" role="src" />
+    <file baseinstalldir="/" name="src/php/ext/grpc/server.c" role="src" />
+    <file baseinstalldir="/" name="src/php/ext/grpc/server_credentials.c" role="src" />
+    <file baseinstalldir="/" name="src/php/ext/grpc/timeval.c" role="src" />
+    <file baseinstalldir="/" name="src/php/ext/grpc/byte_buffer.h" role="src" />
+    <file baseinstalldir="/" name="src/php/ext/grpc/call.h" role="src" />
+    <file baseinstalldir="/" name="src/php/ext/grpc/call_credentials.h" role="src" />
+    <file baseinstalldir="/" name="src/php/ext/grpc/channel.h" role="src" />
+    <file baseinstalldir="/" name="src/php/ext/grpc/channel_credentials.h" role="src" />
+    <file baseinstalldir="/" name="src/php/ext/grpc/completion_queue.h" role="src" />
+    <file baseinstalldir="/" name="src/php/ext/grpc/php_grpc.h" role="src" />
+    <file baseinstalldir="/" name="src/php/ext/grpc/server.h" role="src" />
+    <file baseinstalldir="/" name="src/php/ext/grpc/server_credentials.h" role="src" />
+    <file baseinstalldir="/" name="src/php/ext/grpc/timeval.h" role="src" />
+    <file baseinstalldir="/" name="include/grpc/support/alloc.h" role="src" />
+    <file baseinstalldir="/" name="include/grpc/support/atm.h" role="src" />
+    <file baseinstalldir="/" name="include/grpc/support/atm_gcc_atomic.h" role="src" />
+    <file baseinstalldir="/" name="include/grpc/support/atm_gcc_sync.h" role="src" />
+    <file baseinstalldir="/" name="include/grpc/support/atm_win32.h" role="src" />
+    <file baseinstalldir="/" name="include/grpc/support/avl.h" role="src" />
+    <file baseinstalldir="/" name="include/grpc/support/cmdline.h" role="src" />
+    <file baseinstalldir="/" name="include/grpc/support/cpu.h" role="src" />
+    <file baseinstalldir="/" name="include/grpc/support/histogram.h" role="src" />
+    <file baseinstalldir="/" name="include/grpc/support/host_port.h" role="src" />
+    <file baseinstalldir="/" name="include/grpc/support/log.h" role="src" />
+    <file baseinstalldir="/" name="include/grpc/support/log_win32.h" role="src" />
+    <file baseinstalldir="/" name="include/grpc/support/port_platform.h" role="src" />
+    <file baseinstalldir="/" name="include/grpc/support/slice.h" role="src" />
+    <file baseinstalldir="/" name="include/grpc/support/slice_buffer.h" role="src" />
+    <file baseinstalldir="/" name="include/grpc/support/string_util.h" role="src" />
+    <file baseinstalldir="/" name="include/grpc/support/subprocess.h" role="src" />
+    <file baseinstalldir="/" name="include/grpc/support/sync.h" role="src" />
+    <file baseinstalldir="/" name="include/grpc/support/sync_generic.h" role="src" />
+    <file baseinstalldir="/" name="include/grpc/support/sync_posix.h" role="src" />
+    <file baseinstalldir="/" name="include/grpc/support/sync_win32.h" role="src" />
+    <file baseinstalldir="/" name="include/grpc/support/thd.h" role="src" />
+    <file baseinstalldir="/" name="include/grpc/support/time.h" role="src" />
+    <file baseinstalldir="/" name="include/grpc/support/tls.h" role="src" />
+    <file baseinstalldir="/" name="include/grpc/support/tls_gcc.h" role="src" />
+    <file baseinstalldir="/" name="include/grpc/support/tls_msvc.h" role="src" />
+    <file baseinstalldir="/" name="include/grpc/support/tls_pthread.h" role="src" />
+    <file baseinstalldir="/" name="include/grpc/support/useful.h" role="src" />
+    <file baseinstalldir="/" name="include/grpc/impl/codegen/alloc.h" role="src" />
+    <file baseinstalldir="/" name="include/grpc/impl/codegen/atm.h" role="src" />
+    <file baseinstalldir="/" name="include/grpc/impl/codegen/atm_gcc_atomic.h" role="src" />
+    <file baseinstalldir="/" name="include/grpc/impl/codegen/atm_gcc_sync.h" role="src" />
+    <file baseinstalldir="/" name="include/grpc/impl/codegen/atm_win32.h" role="src" />
+    <file baseinstalldir="/" name="include/grpc/impl/codegen/log.h" role="src" />
+    <file baseinstalldir="/" name="include/grpc/impl/codegen/port_platform.h" role="src" />
+    <file baseinstalldir="/" name="include/grpc/impl/codegen/slice.h" role="src" />
+    <file baseinstalldir="/" name="include/grpc/impl/codegen/slice_buffer.h" role="src" />
+    <file baseinstalldir="/" name="include/grpc/impl/codegen/sync.h" role="src" />
+    <file baseinstalldir="/" name="include/grpc/impl/codegen/sync_generic.h" role="src" />
+    <file baseinstalldir="/" name="include/grpc/impl/codegen/sync_posix.h" role="src" />
+    <file baseinstalldir="/" name="include/grpc/impl/codegen/sync_win32.h" role="src" />
+    <file baseinstalldir="/" name="include/grpc/impl/codegen/time.h" role="src" />
+    <file baseinstalldir="/" name="src/core/profiling/timers.h" role="src" />
+    <file baseinstalldir="/" name="src/core/support/block_annotate.h" role="src" />
+    <file baseinstalldir="/" name="src/core/support/env.h" role="src" />
+    <file baseinstalldir="/" name="src/core/support/load_file.h" role="src" />
+    <file baseinstalldir="/" name="src/core/support/murmur_hash.h" role="src" />
+    <file baseinstalldir="/" name="src/core/support/stack_lockfree.h" role="src" />
+    <file baseinstalldir="/" name="src/core/support/string.h" role="src" />
+    <file baseinstalldir="/" name="src/core/support/string_win32.h" role="src" />
+    <file baseinstalldir="/" name="src/core/support/thd_internal.h" role="src" />
+    <file baseinstalldir="/" name="src/core/support/time_precise.h" role="src" />
+    <file baseinstalldir="/" name="src/core/support/tmpfile.h" role="src" />
+    <file baseinstalldir="/" name="src/core/profiling/basic_timers.c" role="src" />
+    <file baseinstalldir="/" name="src/core/profiling/stap_timers.c" role="src" />
+    <file baseinstalldir="/" name="src/core/support/alloc.c" role="src" />
+    <file baseinstalldir="/" name="src/core/support/avl.c" role="src" />
+    <file baseinstalldir="/" name="src/core/support/cmdline.c" role="src" />
+    <file baseinstalldir="/" name="src/core/support/cpu_iphone.c" role="src" />
+    <file baseinstalldir="/" name="src/core/support/cpu_linux.c" role="src" />
+    <file baseinstalldir="/" name="src/core/support/cpu_posix.c" role="src" />
+    <file baseinstalldir="/" name="src/core/support/cpu_windows.c" role="src" />
+    <file baseinstalldir="/" name="src/core/support/env_linux.c" role="src" />
+    <file baseinstalldir="/" name="src/core/support/env_posix.c" role="src" />
+    <file baseinstalldir="/" name="src/core/support/env_win32.c" role="src" />
+    <file baseinstalldir="/" name="src/core/support/histogram.c" role="src" />
+    <file baseinstalldir="/" name="src/core/support/host_port.c" role="src" />
+    <file baseinstalldir="/" name="src/core/support/load_file.c" role="src" />
+    <file baseinstalldir="/" name="src/core/support/log.c" role="src" />
+    <file baseinstalldir="/" name="src/core/support/log_android.c" role="src" />
+    <file baseinstalldir="/" name="src/core/support/log_linux.c" role="src" />
+    <file baseinstalldir="/" name="src/core/support/log_posix.c" role="src" />
+    <file baseinstalldir="/" name="src/core/support/log_win32.c" role="src" />
+    <file baseinstalldir="/" name="src/core/support/murmur_hash.c" role="src" />
+    <file baseinstalldir="/" name="src/core/support/slice.c" role="src" />
+    <file baseinstalldir="/" name="src/core/support/slice_buffer.c" role="src" />
+    <file baseinstalldir="/" name="src/core/support/stack_lockfree.c" role="src" />
+    <file baseinstalldir="/" name="src/core/support/string.c" role="src" />
+    <file baseinstalldir="/" name="src/core/support/string_posix.c" role="src" />
+    <file baseinstalldir="/" name="src/core/support/string_win32.c" role="src" />
+    <file baseinstalldir="/" name="src/core/support/subprocess_posix.c" role="src" />
+    <file baseinstalldir="/" name="src/core/support/subprocess_windows.c" role="src" />
+    <file baseinstalldir="/" name="src/core/support/sync.c" role="src" />
+    <file baseinstalldir="/" name="src/core/support/sync_posix.c" role="src" />
+    <file baseinstalldir="/" name="src/core/support/sync_win32.c" role="src" />
+    <file baseinstalldir="/" name="src/core/support/thd.c" role="src" />
+    <file baseinstalldir="/" name="src/core/support/thd_posix.c" role="src" />
+    <file baseinstalldir="/" name="src/core/support/thd_win32.c" role="src" />
+    <file baseinstalldir="/" name="src/core/support/time.c" role="src" />
+    <file baseinstalldir="/" name="src/core/support/time_posix.c" role="src" />
+    <file baseinstalldir="/" name="src/core/support/time_precise.c" role="src" />
+    <file baseinstalldir="/" name="src/core/support/time_win32.c" role="src" />
+    <file baseinstalldir="/" name="src/core/support/tls_pthread.c" role="src" />
+    <file baseinstalldir="/" name="src/core/support/tmpfile_posix.c" role="src" />
+    <file baseinstalldir="/" name="src/core/support/tmpfile_win32.c" role="src" />
+    <file baseinstalldir="/" name="src/core/support/wrap_memcpy.c" role="src" />
+    <file baseinstalldir="/" name="include/grpc/grpc_security.h" role="src" />
+    <file baseinstalldir="/" name="include/grpc/byte_buffer.h" role="src" />
+    <file baseinstalldir="/" name="include/grpc/byte_buffer_reader.h" role="src" />
+    <file baseinstalldir="/" name="include/grpc/compression.h" role="src" />
+    <file baseinstalldir="/" name="include/grpc/grpc.h" role="src" />
+    <file baseinstalldir="/" name="include/grpc/status.h" role="src" />
+    <file baseinstalldir="/" name="include/grpc/census.h" role="src" />
+    <file baseinstalldir="/" name="src/core/census/grpc_filter.h" role="src" />
+    <file baseinstalldir="/" name="src/core/channel/channel_args.h" role="src" />
+    <file baseinstalldir="/" name="src/core/channel/channel_stack.h" role="src" />
+    <file baseinstalldir="/" name="src/core/channel/client_channel.h" role="src" />
+    <file baseinstalldir="/" name="src/core/channel/client_uchannel.h" role="src" />
+    <file baseinstalldir="/" name="src/core/channel/compress_filter.h" role="src" />
+    <file baseinstalldir="/" name="src/core/channel/connected_channel.h" role="src" />
+    <file baseinstalldir="/" name="src/core/channel/context.h" role="src" />
+    <file baseinstalldir="/" name="src/core/channel/http_client_filter.h" role="src" />
+    <file baseinstalldir="/" name="src/core/channel/http_server_filter.h" role="src" />
+    <file baseinstalldir="/" name="src/core/channel/subchannel_call_holder.h" role="src" />
+    <file baseinstalldir="/" name="src/core/client_config/client_config.h" role="src" />
+    <file baseinstalldir="/" name="src/core/client_config/connector.h" role="src" />
+    <file baseinstalldir="/" name="src/core/client_config/initial_connect_string.h" role="src" />
+    <file baseinstalldir="/" name="src/core/client_config/lb_policies/load_balancer_api.h" role="src" />
+    <file baseinstalldir="/" name="src/core/client_config/lb_policies/pick_first.h" role="src" />
+    <file baseinstalldir="/" name="src/core/client_config/lb_policies/round_robin.h" role="src" />
+    <file baseinstalldir="/" name="src/core/client_config/lb_policy.h" role="src" />
+    <file baseinstalldir="/" name="src/core/client_config/lb_policy_factory.h" role="src" />
+    <file baseinstalldir="/" name="src/core/client_config/lb_policy_registry.h" role="src" />
+    <file baseinstalldir="/" name="src/core/client_config/resolver.h" role="src" />
+    <file baseinstalldir="/" name="src/core/client_config/resolver_factory.h" role="src" />
+    <file baseinstalldir="/" name="src/core/client_config/resolver_registry.h" role="src" />
+    <file baseinstalldir="/" name="src/core/client_config/resolvers/dns_resolver.h" role="src" />
+    <file baseinstalldir="/" name="src/core/client_config/resolvers/sockaddr_resolver.h" role="src" />
+    <file baseinstalldir="/" name="src/core/client_config/subchannel.h" role="src" />
+    <file baseinstalldir="/" name="src/core/client_config/subchannel_factory.h" role="src" />
+    <file baseinstalldir="/" name="src/core/client_config/subchannel_index.h" role="src" />
+    <file baseinstalldir="/" name="src/core/client_config/uri_parser.h" role="src" />
+    <file baseinstalldir="/" name="src/core/compression/algorithm_metadata.h" role="src" />
+    <file baseinstalldir="/" name="src/core/compression/message_compress.h" role="src" />
+    <file baseinstalldir="/" name="src/core/debug/trace.h" role="src" />
+    <file baseinstalldir="/" name="src/core/httpcli/format_request.h" role="src" />
+    <file baseinstalldir="/" name="src/core/httpcli/httpcli.h" role="src" />
+    <file baseinstalldir="/" name="src/core/httpcli/parser.h" role="src" />
+    <file baseinstalldir="/" name="src/core/iomgr/closure.h" role="src" />
+    <file baseinstalldir="/" name="src/core/iomgr/endpoint.h" role="src" />
+    <file baseinstalldir="/" name="src/core/iomgr/endpoint_pair.h" role="src" />
+    <file baseinstalldir="/" name="src/core/iomgr/exec_ctx.h" role="src" />
+    <file baseinstalldir="/" name="src/core/iomgr/executor.h" role="src" />
+    <file baseinstalldir="/" name="src/core/iomgr/fd_posix.h" role="src" />
+    <file baseinstalldir="/" name="src/core/iomgr/iocp_windows.h" role="src" />
+    <file baseinstalldir="/" name="src/core/iomgr/iomgr.h" role="src" />
+    <file baseinstalldir="/" name="src/core/iomgr/iomgr_internal.h" role="src" />
+    <file baseinstalldir="/" name="src/core/iomgr/iomgr_posix.h" role="src" />
+    <file baseinstalldir="/" name="src/core/iomgr/pollset.h" role="src" />
+    <file baseinstalldir="/" name="src/core/iomgr/pollset_posix.h" role="src" />
+    <file baseinstalldir="/" name="src/core/iomgr/pollset_set.h" role="src" />
+    <file baseinstalldir="/" name="src/core/iomgr/pollset_set_posix.h" role="src" />
+    <file baseinstalldir="/" name="src/core/iomgr/pollset_set_windows.h" role="src" />
+    <file baseinstalldir="/" name="src/core/iomgr/pollset_windows.h" role="src" />
+    <file baseinstalldir="/" name="src/core/iomgr/resolve_address.h" role="src" />
+    <file baseinstalldir="/" name="src/core/iomgr/sockaddr.h" role="src" />
+    <file baseinstalldir="/" name="src/core/iomgr/sockaddr_posix.h" role="src" />
+    <file baseinstalldir="/" name="src/core/iomgr/sockaddr_utils.h" role="src" />
+    <file baseinstalldir="/" name="src/core/iomgr/sockaddr_win32.h" role="src" />
+    <file baseinstalldir="/" name="src/core/iomgr/socket_utils_posix.h" role="src" />
+    <file baseinstalldir="/" name="src/core/iomgr/socket_windows.h" role="src" />
+    <file baseinstalldir="/" name="src/core/iomgr/tcp_client.h" role="src" />
+    <file baseinstalldir="/" name="src/core/iomgr/tcp_posix.h" role="src" />
+    <file baseinstalldir="/" name="src/core/iomgr/tcp_server.h" role="src" />
+    <file baseinstalldir="/" name="src/core/iomgr/tcp_windows.h" role="src" />
+    <file baseinstalldir="/" name="src/core/iomgr/time_averaged_stats.h" role="src" />
+    <file baseinstalldir="/" name="src/core/iomgr/timer.h" role="src" />
+    <file baseinstalldir="/" name="src/core/iomgr/timer_heap.h" role="src" />
+    <file baseinstalldir="/" name="src/core/iomgr/udp_server.h" role="src" />
+    <file baseinstalldir="/" name="src/core/iomgr/wakeup_fd_pipe.h" role="src" />
+    <file baseinstalldir="/" name="src/core/iomgr/wakeup_fd_posix.h" role="src" />
+    <file baseinstalldir="/" name="src/core/iomgr/workqueue.h" role="src" />
+    <file baseinstalldir="/" name="src/core/iomgr/workqueue_posix.h" role="src" />
+    <file baseinstalldir="/" name="src/core/iomgr/workqueue_windows.h" role="src" />
+    <file baseinstalldir="/" name="src/core/json/json.h" role="src" />
+    <file baseinstalldir="/" name="src/core/json/json_common.h" role="src" />
+    <file baseinstalldir="/" name="src/core/json/json_reader.h" role="src" />
+    <file baseinstalldir="/" name="src/core/json/json_writer.h" role="src" />
+    <file baseinstalldir="/" name="src/core/proto/grpc/lb/v0/load_balancer.pb.h" role="src" />
+    <file baseinstalldir="/" name="src/core/statistics/census_interface.h" role="src" />
+    <file baseinstalldir="/" name="src/core/statistics/census_rpc_stats.h" role="src" />
+    <file baseinstalldir="/" name="src/core/surface/api_trace.h" role="src" />
+    <file baseinstalldir="/" name="src/core/surface/call.h" role="src" />
+    <file baseinstalldir="/" name="src/core/surface/call_test_only.h" role="src" />
+    <file baseinstalldir="/" name="src/core/surface/channel.h" role="src" />
+    <file baseinstalldir="/" name="src/core/surface/completion_queue.h" role="src" />
+    <file baseinstalldir="/" name="src/core/surface/event_string.h" role="src" />
+    <file baseinstalldir="/" name="src/core/surface/init.h" role="src" />
+    <file baseinstalldir="/" name="src/core/surface/server.h" role="src" />
+    <file baseinstalldir="/" name="src/core/surface/surface_trace.h" role="src" />
+    <file baseinstalldir="/" name="src/core/transport/byte_stream.h" role="src" />
+    <file baseinstalldir="/" name="src/core/transport/chttp2/alpn.h" role="src" />
+    <file baseinstalldir="/" name="src/core/transport/chttp2/bin_encoder.h" role="src" />
+    <file baseinstalldir="/" name="src/core/transport/chttp2/frame.h" role="src" />
+    <file baseinstalldir="/" name="src/core/transport/chttp2/frame_data.h" role="src" />
+    <file baseinstalldir="/" name="src/core/transport/chttp2/frame_goaway.h" role="src" />
+    <file baseinstalldir="/" name="src/core/transport/chttp2/frame_ping.h" role="src" />
+    <file baseinstalldir="/" name="src/core/transport/chttp2/frame_rst_stream.h" role="src" />
+    <file baseinstalldir="/" name="src/core/transport/chttp2/frame_settings.h" role="src" />
+    <file baseinstalldir="/" name="src/core/transport/chttp2/frame_window_update.h" role="src" />
+    <file baseinstalldir="/" name="src/core/transport/chttp2/hpack_encoder.h" role="src" />
+    <file baseinstalldir="/" name="src/core/transport/chttp2/hpack_parser.h" role="src" />
+    <file baseinstalldir="/" name="src/core/transport/chttp2/hpack_table.h" role="src" />
+    <file baseinstalldir="/" name="src/core/transport/chttp2/http2_errors.h" role="src" />
+    <file baseinstalldir="/" name="src/core/transport/chttp2/huffsyms.h" role="src" />
+    <file baseinstalldir="/" name="src/core/transport/chttp2/incoming_metadata.h" role="src" />
+    <file baseinstalldir="/" name="src/core/transport/chttp2/internal.h" role="src" />
+    <file baseinstalldir="/" name="src/core/transport/chttp2/status_conversion.h" role="src" />
+    <file baseinstalldir="/" name="src/core/transport/chttp2/stream_map.h" role="src" />
+    <file baseinstalldir="/" name="src/core/transport/chttp2/timeout_encoding.h" role="src" />
+    <file baseinstalldir="/" name="src/core/transport/chttp2/varint.h" role="src" />
+    <file baseinstalldir="/" name="src/core/transport/chttp2_transport.h" role="src" />
+    <file baseinstalldir="/" name="src/core/transport/connectivity_state.h" role="src" />
+    <file baseinstalldir="/" name="src/core/transport/metadata.h" role="src" />
+    <file baseinstalldir="/" name="src/core/transport/metadata_batch.h" role="src" />
+    <file baseinstalldir="/" name="src/core/transport/static_metadata.h" role="src" />
+    <file baseinstalldir="/" name="src/core/transport/transport.h" role="src" />
+    <file baseinstalldir="/" name="src/core/transport/transport_impl.h" role="src" />
+    <file baseinstalldir="/" name="src/core/security/auth_filters.h" role="src" />
+    <file baseinstalldir="/" name="src/core/security/b64.h" role="src" />
+    <file baseinstalldir="/" name="src/core/security/credentials.h" role="src" />
+    <file baseinstalldir="/" name="src/core/security/handshake.h" role="src" />
+    <file baseinstalldir="/" name="src/core/security/json_token.h" role="src" />
+    <file baseinstalldir="/" name="src/core/security/jwt_verifier.h" role="src" />
+    <file baseinstalldir="/" name="src/core/security/secure_endpoint.h" role="src" />
+    <file baseinstalldir="/" name="src/core/security/security_connector.h" role="src" />
+    <file baseinstalldir="/" name="src/core/security/security_context.h" role="src" />
+    <file baseinstalldir="/" name="src/core/tsi/fake_transport_security.h" role="src" />
+    <file baseinstalldir="/" name="src/core/tsi/ssl_transport_security.h" role="src" />
+    <file baseinstalldir="/" name="src/core/tsi/ssl_types.h" role="src" />
+    <file baseinstalldir="/" name="src/core/tsi/transport_security.h" role="src" />
+    <file baseinstalldir="/" name="src/core/tsi/transport_security_interface.h" role="src" />
+    <file baseinstalldir="/" name="src/core/census/aggregation.h" role="src" />
+    <file baseinstalldir="/" name="src/core/census/mlog.h" role="src" />
+    <file baseinstalldir="/" name="src/core/census/rpc_metric_id.h" role="src" />
+    <file baseinstalldir="/" name="third_party/nanopb/pb.h" role="src" />
+    <file baseinstalldir="/" name="third_party/nanopb/pb_common.h" role="src" />
+    <file baseinstalldir="/" name="third_party/nanopb/pb_decode.h" role="src" />
+    <file baseinstalldir="/" name="third_party/nanopb/pb_encode.h" role="src" />
+    <file baseinstalldir="/" name="src/core/census/grpc_context.c" role="src" />
+    <file baseinstalldir="/" name="src/core/census/grpc_filter.c" role="src" />
+    <file baseinstalldir="/" name="src/core/channel/channel_args.c" role="src" />
+    <file baseinstalldir="/" name="src/core/channel/channel_stack.c" role="src" />
+    <file baseinstalldir="/" name="src/core/channel/client_channel.c" role="src" />
+    <file baseinstalldir="/" name="src/core/channel/client_uchannel.c" role="src" />
+    <file baseinstalldir="/" name="src/core/channel/compress_filter.c" role="src" />
+    <file baseinstalldir="/" name="src/core/channel/connected_channel.c" role="src" />
+    <file baseinstalldir="/" name="src/core/channel/http_client_filter.c" role="src" />
+    <file baseinstalldir="/" name="src/core/channel/http_server_filter.c" role="src" />
+    <file baseinstalldir="/" name="src/core/channel/subchannel_call_holder.c" role="src" />
+    <file baseinstalldir="/" name="src/core/client_config/client_config.c" role="src" />
+    <file baseinstalldir="/" name="src/core/client_config/connector.c" role="src" />
+    <file baseinstalldir="/" name="src/core/client_config/default_initial_connect_string.c" role="src" />
+    <file baseinstalldir="/" name="src/core/client_config/initial_connect_string.c" role="src" />
+    <file baseinstalldir="/" name="src/core/client_config/lb_policies/load_balancer_api.c" role="src" />
+    <file baseinstalldir="/" name="src/core/client_config/lb_policies/pick_first.c" role="src" />
+    <file baseinstalldir="/" name="src/core/client_config/lb_policies/round_robin.c" role="src" />
+    <file baseinstalldir="/" name="src/core/client_config/lb_policy.c" role="src" />
+    <file baseinstalldir="/" name="src/core/client_config/lb_policy_factory.c" role="src" />
+    <file baseinstalldir="/" name="src/core/client_config/lb_policy_registry.c" role="src" />
+    <file baseinstalldir="/" name="src/core/client_config/resolver.c" role="src" />
+    <file baseinstalldir="/" name="src/core/client_config/resolver_factory.c" role="src" />
+    <file baseinstalldir="/" name="src/core/client_config/resolver_registry.c" role="src" />
+    <file baseinstalldir="/" name="src/core/client_config/resolvers/dns_resolver.c" role="src" />
+    <file baseinstalldir="/" name="src/core/client_config/resolvers/sockaddr_resolver.c" role="src" />
+    <file baseinstalldir="/" name="src/core/client_config/subchannel.c" role="src" />
+    <file baseinstalldir="/" name="src/core/client_config/subchannel_factory.c" role="src" />
+    <file baseinstalldir="/" name="src/core/client_config/subchannel_index.c" role="src" />
+    <file baseinstalldir="/" name="src/core/client_config/uri_parser.c" role="src" />
+    <file baseinstalldir="/" name="src/core/compression/compression_algorithm.c" role="src" />
+    <file baseinstalldir="/" name="src/core/compression/message_compress.c" role="src" />
+    <file baseinstalldir="/" name="src/core/debug/trace.c" role="src" />
+    <file baseinstalldir="/" name="src/core/httpcli/format_request.c" role="src" />
+    <file baseinstalldir="/" name="src/core/httpcli/httpcli.c" role="src" />
+    <file baseinstalldir="/" name="src/core/httpcli/parser.c" role="src" />
+    <file baseinstalldir="/" name="src/core/iomgr/closure.c" role="src" />
+    <file baseinstalldir="/" name="src/core/iomgr/endpoint.c" role="src" />
+    <file baseinstalldir="/" name="src/core/iomgr/endpoint_pair_posix.c" role="src" />
+    <file baseinstalldir="/" name="src/core/iomgr/endpoint_pair_windows.c" role="src" />
+    <file baseinstalldir="/" name="src/core/iomgr/exec_ctx.c" role="src" />
+    <file baseinstalldir="/" name="src/core/iomgr/executor.c" role="src" />
+    <file baseinstalldir="/" name="src/core/iomgr/fd_posix.c" role="src" />
+    <file baseinstalldir="/" name="src/core/iomgr/iocp_windows.c" role="src" />
+    <file baseinstalldir="/" name="src/core/iomgr/iomgr.c" role="src" />
+    <file baseinstalldir="/" name="src/core/iomgr/iomgr_posix.c" role="src" />
+    <file baseinstalldir="/" name="src/core/iomgr/iomgr_windows.c" role="src" />
+    <file baseinstalldir="/" name="src/core/iomgr/pollset_multipoller_with_epoll.c" role="src" />
+    <file baseinstalldir="/" name="src/core/iomgr/pollset_multipoller_with_poll_posix.c" role="src" />
+    <file baseinstalldir="/" name="src/core/iomgr/pollset_posix.c" role="src" />
+    <file baseinstalldir="/" name="src/core/iomgr/pollset_set_posix.c" role="src" />
+    <file baseinstalldir="/" name="src/core/iomgr/pollset_set_windows.c" role="src" />
+    <file baseinstalldir="/" name="src/core/iomgr/pollset_windows.c" role="src" />
+    <file baseinstalldir="/" name="src/core/iomgr/resolve_address_posix.c" role="src" />
+    <file baseinstalldir="/" name="src/core/iomgr/resolve_address_windows.c" role="src" />
+    <file baseinstalldir="/" name="src/core/iomgr/sockaddr_utils.c" role="src" />
+    <file baseinstalldir="/" name="src/core/iomgr/socket_utils_common_posix.c" role="src" />
+    <file baseinstalldir="/" name="src/core/iomgr/socket_utils_linux.c" role="src" />
+    <file baseinstalldir="/" name="src/core/iomgr/socket_utils_posix.c" role="src" />
+    <file baseinstalldir="/" name="src/core/iomgr/socket_windows.c" role="src" />
+    <file baseinstalldir="/" name="src/core/iomgr/tcp_client_posix.c" role="src" />
+    <file baseinstalldir="/" name="src/core/iomgr/tcp_client_windows.c" role="src" />
+    <file baseinstalldir="/" name="src/core/iomgr/tcp_posix.c" role="src" />
+    <file baseinstalldir="/" name="src/core/iomgr/tcp_server_posix.c" role="src" />
+    <file baseinstalldir="/" name="src/core/iomgr/tcp_server_windows.c" role="src" />
+    <file baseinstalldir="/" name="src/core/iomgr/tcp_windows.c" role="src" />
+    <file baseinstalldir="/" name="src/core/iomgr/time_averaged_stats.c" role="src" />
+    <file baseinstalldir="/" name="src/core/iomgr/timer.c" role="src" />
+    <file baseinstalldir="/" name="src/core/iomgr/timer_heap.c" role="src" />
+    <file baseinstalldir="/" name="src/core/iomgr/udp_server.c" role="src" />
+    <file baseinstalldir="/" name="src/core/iomgr/wakeup_fd_eventfd.c" role="src" />
+    <file baseinstalldir="/" name="src/core/iomgr/wakeup_fd_nospecial.c" role="src" />
+    <file baseinstalldir="/" name="src/core/iomgr/wakeup_fd_pipe.c" role="src" />
+    <file baseinstalldir="/" name="src/core/iomgr/wakeup_fd_posix.c" role="src" />
+    <file baseinstalldir="/" name="src/core/iomgr/workqueue_posix.c" role="src" />
+    <file baseinstalldir="/" name="src/core/iomgr/workqueue_windows.c" role="src" />
+    <file baseinstalldir="/" name="src/core/json/json.c" role="src" />
+    <file baseinstalldir="/" name="src/core/json/json_reader.c" role="src" />
+    <file baseinstalldir="/" name="src/core/json/json_string.c" role="src" />
+    <file baseinstalldir="/" name="src/core/json/json_writer.c" role="src" />
+    <file baseinstalldir="/" name="src/core/proto/grpc/lb/v0/load_balancer.pb.c" role="src" />
+    <file baseinstalldir="/" name="src/core/surface/alarm.c" role="src" />
+    <file baseinstalldir="/" name="src/core/surface/api_trace.c" role="src" />
+    <file baseinstalldir="/" name="src/core/surface/byte_buffer.c" role="src" />
+    <file baseinstalldir="/" name="src/core/surface/byte_buffer_reader.c" role="src" />
+    <file baseinstalldir="/" name="src/core/surface/call.c" role="src" />
+    <file baseinstalldir="/" name="src/core/surface/call_details.c" role="src" />
+    <file baseinstalldir="/" name="src/core/surface/call_log_batch.c" role="src" />
+    <file baseinstalldir="/" name="src/core/surface/channel.c" role="src" />
+    <file baseinstalldir="/" name="src/core/surface/channel_connectivity.c" role="src" />
+    <file baseinstalldir="/" name="src/core/surface/channel_create.c" role="src" />
+    <file baseinstalldir="/" name="src/core/surface/channel_ping.c" role="src" />
+    <file baseinstalldir="/" name="src/core/surface/completion_queue.c" role="src" />
+    <file baseinstalldir="/" name="src/core/surface/event_string.c" role="src" />
+    <file baseinstalldir="/" name="src/core/surface/init.c" role="src" />
+    <file baseinstalldir="/" name="src/core/surface/lame_client.c" role="src" />
+    <file baseinstalldir="/" name="src/core/surface/metadata_array.c" role="src" />
+    <file baseinstalldir="/" name="src/core/surface/server.c" role="src" />
+    <file baseinstalldir="/" name="src/core/surface/server_chttp2.c" role="src" />
+    <file baseinstalldir="/" name="src/core/surface/server_create.c" role="src" />
+    <file baseinstalldir="/" name="src/core/surface/validate_metadata.c" role="src" />
+    <file baseinstalldir="/" name="src/core/surface/version.c" role="src" />
+    <file baseinstalldir="/" name="src/core/transport/byte_stream.c" role="src" />
+    <file baseinstalldir="/" name="src/core/transport/chttp2/alpn.c" role="src" />
+    <file baseinstalldir="/" name="src/core/transport/chttp2/bin_encoder.c" role="src" />
+    <file baseinstalldir="/" name="src/core/transport/chttp2/frame_data.c" role="src" />
+    <file baseinstalldir="/" name="src/core/transport/chttp2/frame_goaway.c" role="src" />
+    <file baseinstalldir="/" name="src/core/transport/chttp2/frame_ping.c" role="src" />
+    <file baseinstalldir="/" name="src/core/transport/chttp2/frame_rst_stream.c" role="src" />
+    <file baseinstalldir="/" name="src/core/transport/chttp2/frame_settings.c" role="src" />
+    <file baseinstalldir="/" name="src/core/transport/chttp2/frame_window_update.c" role="src" />
+    <file baseinstalldir="/" name="src/core/transport/chttp2/hpack_encoder.c" role="src" />
+    <file baseinstalldir="/" name="src/core/transport/chttp2/hpack_parser.c" role="src" />
+    <file baseinstalldir="/" name="src/core/transport/chttp2/hpack_table.c" role="src" />
+    <file baseinstalldir="/" name="src/core/transport/chttp2/huffsyms.c" role="src" />
+    <file baseinstalldir="/" name="src/core/transport/chttp2/incoming_metadata.c" role="src" />
+    <file baseinstalldir="/" name="src/core/transport/chttp2/parsing.c" role="src" />
+    <file baseinstalldir="/" name="src/core/transport/chttp2/status_conversion.c" role="src" />
+    <file baseinstalldir="/" name="src/core/transport/chttp2/stream_lists.c" role="src" />
+    <file baseinstalldir="/" name="src/core/transport/chttp2/stream_map.c" role="src" />
+    <file baseinstalldir="/" name="src/core/transport/chttp2/timeout_encoding.c" role="src" />
+    <file baseinstalldir="/" name="src/core/transport/chttp2/varint.c" role="src" />
+    <file baseinstalldir="/" name="src/core/transport/chttp2/writing.c" role="src" />
+    <file baseinstalldir="/" name="src/core/transport/chttp2_transport.c" role="src" />
+    <file baseinstalldir="/" name="src/core/transport/connectivity_state.c" role="src" />
+    <file baseinstalldir="/" name="src/core/transport/metadata.c" role="src" />
+    <file baseinstalldir="/" name="src/core/transport/metadata_batch.c" role="src" />
+    <file baseinstalldir="/" name="src/core/transport/static_metadata.c" role="src" />
+    <file baseinstalldir="/" name="src/core/transport/transport.c" role="src" />
+    <file baseinstalldir="/" name="src/core/transport/transport_op_string.c" role="src" />
+    <file baseinstalldir="/" name="src/core/httpcli/httpcli_security_connector.c" role="src" />
+    <file baseinstalldir="/" name="src/core/security/b64.c" role="src" />
+    <file baseinstalldir="/" name="src/core/security/client_auth_filter.c" role="src" />
+    <file baseinstalldir="/" name="src/core/security/credentials.c" role="src" />
+    <file baseinstalldir="/" name="src/core/security/credentials_metadata.c" role="src" />
+    <file baseinstalldir="/" name="src/core/security/credentials_posix.c" role="src" />
+    <file baseinstalldir="/" name="src/core/security/credentials_win32.c" role="src" />
+    <file baseinstalldir="/" name="src/core/security/google_default_credentials.c" role="src" />
+    <file baseinstalldir="/" name="src/core/security/handshake.c" role="src" />
+    <file baseinstalldir="/" name="src/core/security/json_token.c" role="src" />
+    <file baseinstalldir="/" name="src/core/security/jwt_verifier.c" role="src" />
+    <file baseinstalldir="/" name="src/core/security/secure_endpoint.c" role="src" />
+    <file baseinstalldir="/" name="src/core/security/security_connector.c" role="src" />
+    <file baseinstalldir="/" name="src/core/security/security_context.c" role="src" />
+    <file baseinstalldir="/" name="src/core/security/server_auth_filter.c" role="src" />
+    <file baseinstalldir="/" name="src/core/security/server_secure_chttp2.c" role="src" />
+    <file baseinstalldir="/" name="src/core/surface/init_secure.c" role="src" />
+    <file baseinstalldir="/" name="src/core/surface/secure_channel_create.c" role="src" />
+    <file baseinstalldir="/" name="src/core/tsi/fake_transport_security.c" role="src" />
+    <file baseinstalldir="/" name="src/core/tsi/ssl_transport_security.c" role="src" />
+    <file baseinstalldir="/" name="src/core/tsi/transport_security.c" role="src" />
+    <file baseinstalldir="/" name="src/core/census/context.c" role="src" />
+    <file baseinstalldir="/" name="src/core/census/initialize.c" role="src" />
+    <file baseinstalldir="/" name="src/core/census/mlog.c" role="src" />
+    <file baseinstalldir="/" name="src/core/census/operation.c" role="src" />
+    <file baseinstalldir="/" name="src/core/census/placeholders.c" role="src" />
+    <file baseinstalldir="/" name="src/core/census/tracing.c" role="src" />
+    <file baseinstalldir="/" name="third_party/nanopb/pb_common.c" role="src" />
+    <file baseinstalldir="/" name="third_party/nanopb/pb_decode.c" role="src" />
+    <file baseinstalldir="/" name="third_party/nanopb/pb_encode.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/aes/internal.h" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/asn1/asn1_locl.h" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/bio/internal.h" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/bn/internal.h" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/bn/rsaz_exp.h" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/bytestring/internal.h" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/cipher/internal.h" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/conf/conf_def.h" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/conf/internal.h" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/des/internal.h" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/dh/internal.h" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/digest/internal.h" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/digest/md32_common.h" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/directory.h" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/dsa/internal.h" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/ec/internal.h" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/ec/p256-x86_64-table.h" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/evp/internal.h" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/internal.h" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/modes/internal.h" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/obj/obj_dat.h" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/obj/obj_xref.h" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/pkcs8/internal.h" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/rand/internal.h" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/rsa/internal.h" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/test/scoped_types.h" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/test/test_util.h" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/x509/charmap.h" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/x509/vpm_int.h" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/x509v3/ext_dat.h" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/x509v3/pcy_int.h" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/include/openssl/aead.h" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/include/openssl/aes.h" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/include/openssl/arm_arch.h" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/include/openssl/asn1.h" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/include/openssl/asn1_mac.h" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/include/openssl/asn1t.h" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/include/openssl/base.h" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/include/openssl/base64.h" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/include/openssl/bio.h" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/include/openssl/blowfish.h" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/include/openssl/bn.h" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/include/openssl/buf.h" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/include/openssl/buffer.h" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/include/openssl/bytestring.h" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/include/openssl/cast.h" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/include/openssl/chacha.h" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/include/openssl/cipher.h" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/include/openssl/cmac.h" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/include/openssl/conf.h" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/include/openssl/cpu.h" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/include/openssl/crypto.h" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/include/openssl/curve25519.h" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/include/openssl/des.h" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/include/openssl/dh.h" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/include/openssl/digest.h" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/include/openssl/dsa.h" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/include/openssl/dtls1.h" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/include/openssl/ec.h" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/include/openssl/ec_key.h" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/include/openssl/ecdh.h" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/include/openssl/ecdsa.h" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/include/openssl/engine.h" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/include/openssl/err.h" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/include/openssl/evp.h" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/include/openssl/ex_data.h" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/include/openssl/hkdf.h" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/include/openssl/hmac.h" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/include/openssl/lhash.h" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/include/openssl/lhash_macros.h" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/include/openssl/md4.h" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/include/openssl/md5.h" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/include/openssl/mem.h" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/include/openssl/obj.h" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/include/openssl/obj_mac.h" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/include/openssl/objects.h" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/include/openssl/opensslfeatures.h" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/include/openssl/opensslv.h" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/include/openssl/ossl_typ.h" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/include/openssl/pem.h" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/include/openssl/pkcs12.h" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/include/openssl/pkcs7.h" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/include/openssl/pkcs8.h" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/include/openssl/poly1305.h" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/include/openssl/pqueue.h" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/include/openssl/rand.h" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/include/openssl/rc4.h" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/include/openssl/rsa.h" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/include/openssl/safestack.h" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/include/openssl/sha.h" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/include/openssl/srtp.h" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/include/openssl/ssl.h" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/include/openssl/ssl3.h" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/include/openssl/stack.h" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/include/openssl/stack_macros.h" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/include/openssl/thread.h" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/include/openssl/time_support.h" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/include/openssl/tls1.h" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/include/openssl/type_check.h" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/include/openssl/x509.h" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/include/openssl/x509_vfy.h" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/include/openssl/x509v3.h" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/ssl/internal.h" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/ssl/test/async_bio.h" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/ssl/test/packeted_bio.h" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/ssl/test/scoped_types.h" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/ssl/test/test_config.h" role="src" />
+    <file baseinstalldir="/" name="src/boringssl/err_data.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/aes/aes.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/aes/mode_wrappers.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/asn1/a_bitstr.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/asn1/a_bool.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/asn1/a_bytes.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/asn1/a_d2i_fp.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/asn1/a_dup.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/asn1/a_enum.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/asn1/a_gentm.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/asn1/a_i2d_fp.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/asn1/a_int.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/asn1/a_mbstr.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/asn1/a_object.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/asn1/a_octet.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/asn1/a_print.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/asn1/a_strnid.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/asn1/a_time.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/asn1/a_type.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/asn1/a_utctm.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/asn1/a_utf8.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/asn1/asn1_lib.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/asn1/asn1_par.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/asn1/asn_pack.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/asn1/bio_asn1.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/asn1/bio_ndef.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/asn1/f_enum.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/asn1/f_int.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/asn1/f_string.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/asn1/t_bitst.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/asn1/t_pkey.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/asn1/tasn_dec.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/asn1/tasn_enc.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/asn1/tasn_fre.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/asn1/tasn_new.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/asn1/tasn_prn.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/asn1/tasn_typ.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/asn1/tasn_utl.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/asn1/x_bignum.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/asn1/x_long.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/base64/base64.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/bio/bio.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/bio/bio_mem.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/bio/buffer.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/bio/connect.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/bio/fd.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/bio/file.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/bio/hexdump.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/bio/pair.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/bio/printf.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/bio/socket.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/bio/socket_helper.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/bn/add.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/bn/asm/x86_64-gcc.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/bn/bn.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/bn/bn_asn1.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/bn/cmp.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/bn/convert.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/bn/ctx.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/bn/div.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/bn/exponentiation.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/bn/gcd.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/bn/generic.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/bn/kronecker.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/bn/montgomery.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/bn/mul.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/bn/prime.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/bn/random.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/bn/rsaz_exp.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/bn/shift.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/bn/sqrt.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/buf/buf.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/bytestring/ber.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/bytestring/cbb.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/bytestring/cbs.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/chacha/chacha_generic.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/chacha/chacha_vec.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/cipher/aead.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/cipher/cipher.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/cipher/derive_key.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/cipher/e_aes.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/cipher/e_chacha20poly1305.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/cipher/e_des.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/cipher/e_null.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/cipher/e_rc2.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/cipher/e_rc4.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/cipher/e_ssl3.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/cipher/e_tls.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/cipher/tls_cbc.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/cmac/cmac.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/conf/conf.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/cpu-arm.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/cpu-intel.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/crypto.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/curve25519/curve25519.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/des/des.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/dh/check.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/dh/dh.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/dh/dh_asn1.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/dh/params.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/digest/digest.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/digest/digests.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/directory_posix.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/directory_win.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/dsa/dsa.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/dsa/dsa_asn1.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/ec/ec.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/ec/ec_asn1.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/ec/ec_key.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/ec/ec_montgomery.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/ec/oct.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/ec/p224-64.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/ec/p256-64.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/ec/p256-x86_64.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/ec/simple.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/ec/util-64.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/ec/wnaf.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/ecdh/ecdh.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/ecdsa/ecdsa.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/ecdsa/ecdsa_asn1.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/engine/engine.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/err/err.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/evp/algorithm.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/evp/digestsign.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/evp/evp.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/evp/evp_asn1.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/evp/evp_ctx.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/evp/p_dsa_asn1.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/evp/p_ec.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/evp/p_ec_asn1.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/evp/p_rsa.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/evp/p_rsa_asn1.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/evp/pbkdf.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/evp/sign.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/ex_data.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/hkdf/hkdf.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/hmac/hmac.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/lhash/lhash.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/md4/md4.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/md5/md5.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/mem.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/modes/cbc.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/modes/cfb.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/modes/ctr.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/modes/gcm.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/modes/ofb.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/obj/obj.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/obj/obj_xref.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/pem/pem_all.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/pem/pem_info.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/pem/pem_lib.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/pem/pem_oth.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/pem/pem_pk8.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/pem/pem_pkey.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/pem/pem_x509.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/pem/pem_xaux.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/pkcs8/p5_pbe.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/pkcs8/p5_pbev2.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/pkcs8/p8_pkey.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/pkcs8/pkcs8.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/poly1305/poly1305.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/poly1305/poly1305_arm.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/poly1305/poly1305_vec.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/rand/rand.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/rand/urandom.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/rand/windows.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/rc4/rc4.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/refcount_c11.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/refcount_lock.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/rsa/blinding.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/rsa/padding.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/rsa/rsa.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/rsa/rsa_asn1.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/rsa/rsa_impl.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/sha/sha1.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/sha/sha256.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/sha/sha512.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/stack/stack.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/thread.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/thread_none.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/thread_pthread.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/thread_win.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/time_support.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/x509/a_digest.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/x509/a_sign.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/x509/a_strex.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/x509/a_verify.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/x509/asn1_gen.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/x509/by_dir.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/x509/by_file.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/x509/i2d_pr.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/x509/pkcs7.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/x509/t_crl.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/x509/t_req.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/x509/t_x509.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/x509/t_x509a.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/x509/x509.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/x509/x509_att.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/x509/x509_cmp.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/x509/x509_d2.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/x509/x509_def.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/x509/x509_ext.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/x509/x509_lu.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/x509/x509_obj.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/x509/x509_r2x.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/x509/x509_req.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/x509/x509_set.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/x509/x509_trs.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/x509/x509_txt.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/x509/x509_v3.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/x509/x509_vfy.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/x509/x509_vpm.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/x509/x509cset.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/x509/x509name.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/x509/x509rset.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/x509/x509spki.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/x509/x509type.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/x509/x_algor.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/x509/x_all.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/x509/x_attrib.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/x509/x_crl.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/x509/x_exten.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/x509/x_info.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/x509/x_name.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/x509/x_pkey.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/x509/x_pubkey.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/x509/x_req.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/x509/x_sig.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/x509/x_spki.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/x509/x_val.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/x509/x_x509.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/x509/x_x509a.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/x509v3/pcy_cache.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/x509v3/pcy_data.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/x509v3/pcy_lib.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/x509v3/pcy_map.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/x509v3/pcy_node.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/x509v3/pcy_tree.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/x509v3/v3_akey.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/x509v3/v3_akeya.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/x509v3/v3_alt.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/x509v3/v3_bcons.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/x509v3/v3_bitst.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/x509v3/v3_conf.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/x509v3/v3_cpols.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/x509v3/v3_crld.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/x509v3/v3_enum.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/x509v3/v3_extku.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/x509v3/v3_genn.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/x509v3/v3_ia5.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/x509v3/v3_info.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/x509v3/v3_int.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/x509v3/v3_lib.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/x509v3/v3_ncons.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/x509v3/v3_pci.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/x509v3/v3_pcia.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/x509v3/v3_pcons.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/x509v3/v3_pku.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/x509v3/v3_pmaps.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/x509v3/v3_prn.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/x509v3/v3_purp.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/x509v3/v3_skey.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/x509v3/v3_sxnet.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/crypto/x509v3/v3_utl.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/ssl/custom_extensions.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/ssl/d1_both.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/ssl/d1_clnt.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/ssl/d1_lib.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/ssl/d1_meth.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/ssl/d1_pkt.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/ssl/d1_srtp.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/ssl/d1_srvr.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/ssl/dtls_record.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/ssl/pqueue/pqueue.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/ssl/s3_both.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/ssl/s3_clnt.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/ssl/s3_enc.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/ssl/s3_lib.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/ssl/s3_meth.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/ssl/s3_pkt.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/ssl/s3_srvr.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/ssl/ssl_aead_ctx.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/ssl/ssl_asn1.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/ssl/ssl_buffer.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/ssl/ssl_cert.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/ssl/ssl_cipher.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/ssl/ssl_file.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/ssl/ssl_lib.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/ssl/ssl_rsa.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/ssl/ssl_session.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/ssl/ssl_stat.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/ssl/t1_enc.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/ssl/t1_lib.c" role="src" />
+    <file baseinstalldir="/" name="third_party/boringssl/ssl/tls_record.c" role="src" />
+  </dir>
+ </contents>
+ <dependencies>
+  <required>
+   <php>
+    <min>5.5.0</min>
+   </php>
+   <pearinstaller>
+    <min>1.4.0</min>
+   </pearinstaller>
+  </required>
+ </dependencies>
+ <providesextension>grpc</providesextension>
+ <extsrcrelease />
+ <changelog>
+  <release>
+   <version>
+    <release>0.5.0</release>
+    <api>0.5.0</api>
+   </version>
+   <stability>
+    <release>alpha</release>
+    <api>alpha</api>
+   </stability>
+   <date>2015-06-16</date>
+   <license>BSD</license>
+   <notes>
+First alpha release
+   </notes>
+  </release>
+  <release>
+   <version>
+    <release>0.5.1</release>
+    <api>0.5.1</api>
+   </version>
+   <stability>
+    <release>alpha</release>
+    <api>alpha</api>
+   </stability>
+   <date>2015-07-09</date>
+   <license>BSD</license>
+   <notes>
+Update to wrap gRPC C Core version 0.10.0
+   </notes>
+  </release>
+  <release>
+   <version>
+    <release>0.6.0</release>
+    <api>0.6.0</api>
+   </version>
+   <stability>
+    <release>beta</release>
+    <api>beta</api>
+   </stability>
+   <date>2015-09-24</date>
+   <license>BSD</license>
+   <notes>
+- support per message compression disable
+- expose per-call host override option
+- expose connectivity API
+- expose channel target and call peer
+- add user-agent
+- update to wrap gRPC C core library beta version 0.11.0
+   </notes>
+  </release>
+  <release>
+   <version>
+    <release>0.6.1</release>
+    <api>0.6.0</api>
+   </version>
+   <stability>
+    <release>beta</release>
+    <api>beta</api>
+   </stability>
+   <date>2015-10-21</date>
+   <license>BSD</license>
+   <notes>
+- fixed undefined constant fatal error when run with apache/nginx #2275
+   </notes>
+  </release>
+  <release>
+   <version>
+    <release>0.7.0</release>
+    <api>0.7.0</api>
+   </version>
+   <stability>
+    <release>beta</release>
+    <api>beta</api>
+   </stability>
+   <date>2016-01-13</date>
+   <license>BSD</license>
+   <notes>
+- Breaking change to Credentials class (removed) #3765
+- Replaced by ChannelCredentials and CallCredentials class #3765
+- New plugin based metadata auth API #4394
+- Explicit ChannelCredentials::createInsecure() call
+   </notes>
+  </release>
+  <release>
+   <version>
+    <release>0.8.0</release>
+    <api>0.8.0</api>
+   </version>
+   <stability>
+    <release>beta</release>
+    <api>beta</api>
+   </stability>
+   <date>2016-02-24</date>
+   <license>BSD</license>
+   <notes>
+- Simplify gRPC PHP installation #4517
+   </notes>
+  </release>
+  <release>
+   <version>
+    <release>0.14.0</release>
+    <api>0.14.0</api>
+   </version>
+   <stability>
+    <release>beta</release>
+    <api>beta</api>
+   </stability>
+   <date>2016-03-01</date>
+   <license>BSD</license>
+   <notes>
+- Increase unit test code coverage #5225
+   </notes>
+  </release>
+ </changelog>
+</package>
diff --git a/setup.py b/setup.py
index 5b9f9b6..cfb578e 100644
--- a/setup.py
+++ b/setup.py
@@ -208,7 +208,6 @@
         '_credentials/roots.pem',
         '_windows/grpc_c.32.python',
         '_windows/grpc_c.64.python',
-        'cygrpc.so',
     ],
 }
 if INSTALL_TESTS:
diff --git a/src/core/census/context.c b/src/core/census/context.c
index e60330d..89b8ee0 100644
--- a/src/core/census/context.c
+++ b/src/core/census/context.c
@@ -60,10 +60,10 @@
 //   limit of 255 for both CENSUS_MAX_TAG_KV_LEN and CENSUS_MAX_PROPAGATED_TAGS.
 // * Keep all tag information (keys/values/flags) in a single memory buffer,
 //   that can be directly copied to the wire.
-// * Binary tags share the same structure as, but are encoded separately from,
-//   non-binary tags. This is primarily because non-binary tags are far more
-//   likely to be repeated across multiple RPC calls, so are more efficiently
-//   cached and compressed in any metadata schemes.
+
+// min and max valid chars in tag keys and values. All printable ASCII is OK.
+#define MIN_VALID_TAG_CHAR 32   // ' '
+#define MAX_VALID_TAG_CHAR 126  // '~'
 
 // Structure representing a set of tags. Essentially a count of number of tags
 // present, and pointer to a chunk of memory that contains the per-tag details.
@@ -77,7 +77,7 @@
   char *kvm;        // key/value memory. Consists of repeated entries of:
   //   Offset  Size  Description
   //     0      1    Key length, including trailing 0. (K)
-  //     1      1    Value length. (V)
+  //     1      1    Value length, including trailing 0 (V)
   //     2      1    Flags
   //     3      K    Key bytes
   //     3 + K  V    Value bytes
@@ -108,19 +108,36 @@
 #define CENSUS_TAG_DELETED CENSUS_TAG_RESERVED
 #define CENSUS_TAG_IS_DELETED(flags) (flags & CENSUS_TAG_DELETED)
 
-// Primary (external) representation of a context. Composed of 3 underlying
-// tag_set structs, one for each of the binary/printable propagated tags, and
-// one for everything else. This is to efficiently support tag
-// encoding/decoding.
+// Primary representation of a context. Composed of 2 underlying tag_set
+// structs, one each for propagated and local (non-propagated) tags. This is
+// to efficiently support tag encoding/decoding.
+// TODO(aveitch): need to add tracing id's/structure.
 struct census_context {
-  struct tag_set tags[3];
+  struct tag_set tags[2];
   census_context_status status;
 };
 
 // Indices into the tags member of census_context
 #define PROPAGATED_TAGS 0
-#define PROPAGATED_BINARY_TAGS 1
-#define LOCAL_TAGS 2
+#define LOCAL_TAGS 1
+
+// Validate (check all characters are in range and size is less than limit) a
+// key or value string. Returns 0 if the string is invalid, or the length
+// (including terminator) if valid.
+static size_t validate_tag(const char *kv) {
+  size_t len = 1;
+  char ch;
+  while ((ch = *kv++) != 0) {
+    if (ch < MIN_VALID_TAG_CHAR || ch > MAX_VALID_TAG_CHAR) {
+      return 0;
+    }
+    len++;
+  }
+  if (len > CENSUS_MAX_TAG_KV_LEN) {
+    return 0;
+  }
+  return len;
+}
 
 // Extract a raw tag given a pointer (raw) to the tag header. Allow for some
 // extra bytes in the tag header (see encode/decode functions for usage: this
@@ -166,9 +183,7 @@
                                size_t key_len) {
   return (
       tag_set_delete_tag(&context->tags[LOCAL_TAGS], tag->key, key_len) ||
-      tag_set_delete_tag(&context->tags[PROPAGATED_TAGS], tag->key, key_len) ||
-      tag_set_delete_tag(&context->tags[PROPAGATED_BINARY_TAGS], tag->key,
-                         key_len));
+      tag_set_delete_tag(&context->tags[PROPAGATED_TAGS], tag->key, key_len));
 }
 
 // Add a tag to a tag_set. Return true on success, false if the tag could
@@ -176,11 +191,11 @@
 // not be called if the tag may already exist (in a non-deleted state) in
 // the tag_set, as that would result in two tags with the same key.
 static bool tag_set_add_tag(struct tag_set *tags, const census_tag *tag,
-                            size_t key_len) {
+                            size_t key_len, size_t value_len) {
   if (tags->ntags == CENSUS_MAX_PROPAGATED_TAGS) {
     return false;
   }
-  const size_t tag_size = key_len + tag->value_len + TAG_HEADER_SIZE;
+  const size_t tag_size = key_len + value_len + TAG_HEADER_SIZE;
   if (tags->kvm_used + tag_size > tags->kvm_size) {
     // allocate new memory if needed
     tags->kvm_size += 2 * CENSUS_MAX_TAG_KV_LEN + TAG_HEADER_SIZE;
@@ -191,13 +206,12 @@
   }
   char *kvp = tags->kvm + tags->kvm_used;
   *kvp++ = (char)key_len;
-  *kvp++ = (char)tag->value_len;
+  *kvp++ = (char)value_len;
   // ensure reserved flags are not used.
-  *kvp++ = (char)(tag->flags & (CENSUS_TAG_PROPAGATE | CENSUS_TAG_STATS |
-                                CENSUS_TAG_BINARY));
+  *kvp++ = (char)(tag->flags & (CENSUS_TAG_PROPAGATE | CENSUS_TAG_STATS));
   memcpy(kvp, tag->key, key_len);
   kvp += key_len;
-  memcpy(kvp, tag->value, tag->value_len);
+  memcpy(kvp, tag->value, value_len);
   tags->kvm_used += tag_size;
   tags->ntags++;
   tags->ntags_alloc++;
@@ -207,30 +221,20 @@
 // Add/modify/delete a tag to/in a context. Caller must validate that tag key
 // etc. are valid.
 static void context_modify_tag(census_context *context, const census_tag *tag,
-                               size_t key_len) {
+                               size_t key_len, size_t value_len) {
   // First delete the tag if it is already present.
   bool deleted = context_delete_tag(context, tag, key_len);
-  // Determine if we need to add it back.
-  bool call_add = tag->value != NULL && tag->value_len != 0;
   bool added = false;
-  if (call_add) {
-    if (CENSUS_TAG_IS_PROPAGATED(tag->flags)) {
-      if (CENSUS_TAG_IS_BINARY(tag->flags)) {
-        added = tag_set_add_tag(&context->tags[PROPAGATED_BINARY_TAGS], tag,
-                                key_len);
-      } else {
-        added = tag_set_add_tag(&context->tags[PROPAGATED_TAGS], tag, key_len);
-      }
-    } else {
-      added = tag_set_add_tag(&context->tags[LOCAL_TAGS], tag, key_len);
-    }
+  if (CENSUS_TAG_IS_PROPAGATED(tag->flags)) {
+    added = tag_set_add_tag(&context->tags[PROPAGATED_TAGS], tag, key_len,
+                            value_len);
+  } else {
+    added =
+        tag_set_add_tag(&context->tags[LOCAL_TAGS], tag, key_len, value_len);
   }
+
   if (deleted) {
-    if (call_add) {
-      context->status.n_modified_tags++;
-    } else {
-      context->status.n_deleted_tags++;
-    }
+    context->status.n_modified_tags++;
   } else {
     if (added) {
       context->status.n_added_tags++;
@@ -292,8 +296,6 @@
     memset(context, 0, sizeof(census_context));
   } else {
     tag_set_copy(&context->tags[PROPAGATED_TAGS], &base->tags[PROPAGATED_TAGS]);
-    tag_set_copy(&context->tags[PROPAGATED_BINARY_TAGS],
-                 &base->tags[PROPAGATED_BINARY_TAGS]);
     tag_set_copy(&context->tags[LOCAL_TAGS], &base->tags[LOCAL_TAGS]);
     memset(&context->status, 0, sizeof(context->status));
   }
@@ -301,22 +303,29 @@
   // the context to add/replace/delete as required.
   for (int i = 0; i < ntags; i++) {
     const census_tag *tag = &tags[i];
-    size_t key_len = strlen(tag->key) + 1;
-    // ignore the tag if it is too long/short.
-    if (key_len != 1 && key_len <= CENSUS_MAX_TAG_KV_LEN &&
-        tag->value_len <= CENSUS_MAX_TAG_KV_LEN) {
-      context_modify_tag(context, tag, key_len);
-    } else {
+    size_t key_len = validate_tag(tag->key);
+    // ignore the tag if it is invalid or too short.
+    if (key_len <= 1) {
       context->status.n_invalid_tags++;
+    } else {
+      if (tag->value != NULL) {
+        size_t value_len = validate_tag(tag->value);
+        if (value_len != 0) {
+          context_modify_tag(context, tag, key_len, value_len);
+        } else {
+          context->status.n_invalid_tags++;
+        }
+      } else {
+        if (context_delete_tag(context, tag, key_len)) {
+          context->status.n_deleted_tags++;
+        }
+      }
     }
   }
   // Remove any deleted tags, update status if needed, and return.
   tag_set_flatten(&context->tags[PROPAGATED_TAGS]);
-  tag_set_flatten(&context->tags[PROPAGATED_BINARY_TAGS]);
   tag_set_flatten(&context->tags[LOCAL_TAGS]);
   context->status.n_propagated_tags = context->tags[PROPAGATED_TAGS].ntags;
-  context->status.n_propagated_binary_tags =
-      context->tags[PROPAGATED_BINARY_TAGS].ntags;
   context->status.n_local_tags = context->tags[LOCAL_TAGS].ntags;
   if (status) {
     *status = &context->status;
@@ -331,7 +340,6 @@
 
 void census_context_destroy(census_context *context) {
   gpr_free(context->tags[PROPAGATED_TAGS].kvm);
-  gpr_free(context->tags[PROPAGATED_BINARY_TAGS].kvm);
   gpr_free(context->tags[LOCAL_TAGS].kvm);
   gpr_free(context);
 }
@@ -343,9 +351,6 @@
   if (context->tags[PROPAGATED_TAGS].ntags != 0) {
     iterator->base = PROPAGATED_TAGS;
     iterator->kvm = context->tags[PROPAGATED_TAGS].kvm;
-  } else if (context->tags[PROPAGATED_BINARY_TAGS].ntags != 0) {
-    iterator->base = PROPAGATED_BINARY_TAGS;
-    iterator->kvm = context->tags[PROPAGATED_BINARY_TAGS].kvm;
   } else if (context->tags[LOCAL_TAGS].ntags != 0) {
     iterator->base = LOCAL_TAGS;
     iterator->kvm = context->tags[LOCAL_TAGS].kvm;
@@ -363,7 +368,6 @@
   iterator->kvm = decode_tag(&raw, iterator->kvm, 0);
   tag->key = raw.key;
   tag->value = raw.value;
-  tag->value_len = raw.value_len;
   tag->flags = raw.flags;
   if (++iterator->index == iterator->context->tags[iterator->base].ntags) {
     do {
@@ -388,7 +392,6 @@
     if (key_len == raw.key_len && memcmp(raw.key, key, key_len) == 0) {
       tag->key = raw.key;
       tag->value = raw.value;
-      tag->value_len = raw.value_len;
       tag->flags = raw.flags;
       return true;
     }
@@ -403,8 +406,6 @@
     return 0;
   }
   if (tag_set_get_tag(&context->tags[PROPAGATED_TAGS], key, key_len, tag) ||
-      tag_set_get_tag(&context->tags[PROPAGATED_BINARY_TAGS], key, key_len,
-                      tag) ||
       tag_set_get_tag(&context->tags[LOCAL_TAGS], key, key_len, tag)) {
     return 1;
   }
@@ -447,21 +448,9 @@
   return ENCODED_HEADER_SIZE + tags->kvm_used;
 }
 
-char *census_context_encode(const census_context *context, char *buffer,
-                            size_t buf_size, size_t *print_buf_size,
-                            size_t *bin_buf_size) {
-  *print_buf_size =
-      tag_set_encode(&context->tags[PROPAGATED_TAGS], buffer, buf_size);
-  if (*print_buf_size == 0) {
-    return NULL;
-  }
-  char *b_buffer = buffer + *print_buf_size;
-  *bin_buf_size = tag_set_encode(&context->tags[PROPAGATED_BINARY_TAGS],
-                                 b_buffer, buf_size - *print_buf_size);
-  if (*bin_buf_size == 0) {
-    return NULL;
-  }
-  return b_buffer;
+size_t census_context_encode(const census_context *context, char *buffer,
+                             size_t buf_size) {
+  return tag_set_encode(&context->tags[PROPAGATED_TAGS], buffer, buf_size);
 }
 
 // Decode a tag set.
@@ -506,8 +495,7 @@
   }
 }
 
-census_context *census_context_decode(const char *buffer, size_t size,
-                                      const char *bin_buffer, size_t bin_size) {
+census_context *census_context_decode(const char *buffer, size_t size) {
   census_context *context = gpr_malloc(sizeof(census_context));
   memset(&context->tags[LOCAL_TAGS], 0, sizeof(struct tag_set));
   if (buffer == NULL) {
@@ -515,16 +503,7 @@
   } else {
     tag_set_decode(&context->tags[PROPAGATED_TAGS], buffer, size);
   }
-  if (bin_buffer == NULL) {
-    memset(&context->tags[PROPAGATED_BINARY_TAGS], 0, sizeof(struct tag_set));
-  } else {
-    tag_set_decode(&context->tags[PROPAGATED_BINARY_TAGS], bin_buffer,
-                   bin_size);
-  }
   memset(&context->status, 0, sizeof(context->status));
   context->status.n_propagated_tags = context->tags[PROPAGATED_TAGS].ntags;
-  context->status.n_propagated_binary_tags =
-      context->tags[PROPAGATED_BINARY_TAGS].ntags;
-  // TODO(aveitch): check that BINARY flag is correct for each type.
   return context;
 }
diff --git a/src/core/census/log.c b/src/core/census/mlog.c
similarity index 99%
rename from src/core/census/log.c
rename to src/core/census/mlog.c
index 91b2694..a2cc46d 100644
--- a/src/core/census/log.c
+++ b/src/core/census/mlog.c
@@ -88,7 +88,7 @@
 // include the name of the structure, which will be passed as the first
 // argument. E.g. cl_block_initialize() will initialize a cl_block.
 
-#include "src/core/census/log.h"
+#include "src/core/census/mlog.h"
 #include <grpc/support/alloc.h>
 #include <grpc/support/atm.h>
 #include <grpc/support/cpu.h>
diff --git a/src/core/census/log.h b/src/core/census/mlog.h
similarity index 96%
rename from src/core/census/log.h
rename to src/core/census/mlog.h
index 05daea0..aaba9e1 100644
--- a/src/core/census/log.h
+++ b/src/core/census/mlog.h
@@ -31,8 +31,10 @@
  *
  */
 
-#ifndef GRPC_INTERNAL_CORE_CENSUS_LOG_H
-#define GRPC_INTERNAL_CORE_CENSUS_LOG_H
+/* A very fast in-memory log, optimized for multiple writers. */
+
+#ifndef GRPC_INTERNAL_CORE_CENSUS_MLOG_H
+#define GRPC_INTERNAL_CORE_CENSUS_MLOG_H
 
 #include <grpc/support/port_platform.h>
 #include <stddef.h>
diff --git a/src/core/channel/client_channel.c b/src/core/channel/client_channel.c
index 7176c01..eeac3c1 100644
--- a/src/core/channel/client_channel.c
+++ b/src/core/channel/client_channel.c
@@ -78,8 +78,8 @@
   int exit_idle_when_lb_policy_arrives;
   /** owning stack */
   grpc_channel_stack *owning_stack;
-  /** interested parties */
-  grpc_pollset_set interested_parties;
+  /** interested parties (owned) */
+  grpc_pollset_set *interested_parties;
 } channel_data;
 
 /** We create one watcher for each new lb_policy that is returned from a
@@ -183,8 +183,8 @@
   chand->incoming_configuration = NULL;
 
   if (lb_policy != NULL) {
-    grpc_pollset_set_add_pollset_set(exec_ctx, &lb_policy->interested_parties,
-                                     &chand->interested_parties);
+    grpc_pollset_set_add_pollset_set(exec_ctx, lb_policy->interested_parties,
+                                     chand->interested_parties);
   }
 
   gpr_mu_lock(&chand->mu_config);
@@ -231,9 +231,8 @@
   }
 
   if (old_lb_policy != NULL) {
-    grpc_pollset_set_del_pollset_set(exec_ctx,
-                                     &old_lb_policy->interested_parties,
-                                     &chand->interested_parties);
+    grpc_pollset_set_del_pollset_set(
+        exec_ctx, old_lb_policy->interested_parties, chand->interested_parties);
     GRPC_LB_POLICY_UNREF(exec_ctx, old_lb_policy, "channel");
   }
 
@@ -254,7 +253,7 @@
 
   GPR_ASSERT(op->set_accept_stream == NULL);
   if (op->bind_pollset != NULL) {
-    grpc_pollset_set_add_pollset(exec_ctx, &chand->interested_parties,
+    grpc_pollset_set_add_pollset(exec_ctx, chand->interested_parties,
                                  op->bind_pollset);
   }
 
@@ -284,8 +283,8 @@
     chand->resolver = NULL;
     if (chand->lb_policy != NULL) {
       grpc_pollset_set_del_pollset_set(exec_ctx,
-                                       &chand->lb_policy->interested_parties,
-                                       &chand->interested_parties);
+                                       chand->lb_policy->interested_parties,
+                                       chand->interested_parties);
       GRPC_LB_POLICY_UNREF(exec_ctx, chand->lb_policy, "channel");
       chand->lb_policy = NULL;
     }
@@ -411,7 +410,7 @@
 
   grpc_connectivity_state_init(&chand->state_tracker, GRPC_CHANNEL_IDLE,
                                "client_channel");
-  grpc_pollset_set_init(&chand->interested_parties);
+  chand->interested_parties = grpc_pollset_set_create();
 }
 
 /* Destructor for channel_data */
@@ -425,12 +424,12 @@
   }
   if (chand->lb_policy != NULL) {
     grpc_pollset_set_del_pollset_set(exec_ctx,
-                                     &chand->lb_policy->interested_parties,
-                                     &chand->interested_parties);
+                                     chand->lb_policy->interested_parties,
+                                     chand->interested_parties);
     GRPC_LB_POLICY_UNREF(exec_ctx, chand->lb_policy, "channel");
   }
   grpc_connectivity_state_destroy(exec_ctx, &chand->state_tracker);
-  grpc_pollset_set_destroy(&chand->interested_parties);
+  grpc_pollset_set_destroy(chand->interested_parties);
   gpr_mu_destroy(&chand->mu_config);
 }
 
@@ -501,7 +500,7 @@
                                        bool iomgr_success) {
   external_connectivity_watcher *w = arg;
   grpc_closure *follow_up = w->on_complete;
-  grpc_pollset_set_del_pollset(exec_ctx, &w->chand->interested_parties,
+  grpc_pollset_set_del_pollset(exec_ctx, w->chand->interested_parties,
                                w->pollset);
   GRPC_CHANNEL_STACK_UNREF(exec_ctx, w->chand->owning_stack,
                            "external_connectivity_watcher");
@@ -517,7 +516,7 @@
   w->chand = chand;
   w->pollset = pollset;
   w->on_complete = on_complete;
-  grpc_pollset_set_add_pollset(exec_ctx, &chand->interested_parties, pollset);
+  grpc_pollset_set_add_pollset(exec_ctx, chand->interested_parties, pollset);
   grpc_closure_init(&w->my_closure, on_external_watch_complete, w);
   GRPC_CHANNEL_STACK_REF(w->chand->owning_stack,
                          "external_connectivity_watcher");
diff --git a/src/core/client_config/lb_policies/load_balancer_api.c b/src/core/client_config/lb_policies/load_balancer_api.c
new file mode 100644
index 0000000..a6b5785
--- /dev/null
+++ b/src/core/client_config/lb_policies/load_balancer_api.c
@@ -0,0 +1,163 @@
+/*
+ *
+ * Copyright 2016, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "src/core/client_config/lb_policies/load_balancer_api.h"
+#include "third_party/nanopb/pb_decode.h"
+#include "third_party/nanopb/pb_encode.h"
+
+#include <grpc/support/alloc.h>
+
+typedef struct decode_serverlist_arg {
+  int first_pass;
+  int i;
+  size_t num_servers;
+  grpc_grpclb_server **servers;
+} decode_serverlist_arg;
+
+/* invoked once for every Server in ServerList */
+static bool decode_serverlist(pb_istream_t *stream, const pb_field_t *field,
+                              void **arg) {
+  decode_serverlist_arg *dec_arg = *arg;
+  if (dec_arg->first_pass != 0) { /* first pass */
+    grpc_grpclb_server server;
+    if (!pb_decode(stream, grpc_lb_v0_Server_fields, &server)) {
+      return false;
+    }
+    dec_arg->num_servers++;
+  } else { /* second pass */
+    grpc_grpclb_server *server = gpr_malloc(sizeof(grpc_grpclb_server));
+    GPR_ASSERT(dec_arg->num_servers > 0);
+    if (dec_arg->i == 0) { /* first iteration of second pass */
+      dec_arg->servers =
+          gpr_malloc(sizeof(grpc_grpclb_server *) * dec_arg->num_servers);
+    }
+    if (!pb_decode(stream, grpc_lb_v0_Server_fields, server)) {
+      return false;
+    }
+    dec_arg->servers[dec_arg->i++] = server;
+  }
+
+  return true;
+}
+
+grpc_grpclb_request *grpc_grpclb_request_create(const char *lb_service_name) {
+  grpc_grpclb_request *req = gpr_malloc(sizeof(grpc_grpclb_request));
+
+  req->has_client_stats = 0; /* TODO(dgq): add support for stats once defined */
+  req->has_initial_request = 1;
+  req->initial_request.has_name = 1;
+  strncpy(req->initial_request.name, lb_service_name,
+          GRPC_GRPCLB_SERVICE_NAME_MAX_LENGTH);
+  return req;
+}
+
+gpr_slice grpc_grpclb_request_encode(const grpc_grpclb_request *request) {
+  size_t encoded_length;
+  pb_ostream_t sizestream;
+  pb_ostream_t outputstream;
+  gpr_slice slice;
+  memset(&sizestream, 0, sizeof(pb_ostream_t));
+  pb_encode(&sizestream, grpc_lb_v0_LoadBalanceRequest_fields, request);
+  encoded_length = sizestream.bytes_written;
+
+  slice = gpr_slice_malloc(encoded_length);
+  outputstream =
+      pb_ostream_from_buffer(GPR_SLICE_START_PTR(slice), encoded_length);
+  GPR_ASSERT(pb_encode(&outputstream, grpc_lb_v0_LoadBalanceRequest_fields,
+                       request) != 0);
+  return slice;
+}
+
+void grpc_grpclb_request_destroy(grpc_grpclb_request *request) {
+  gpr_free(request);
+}
+
+grpc_grpclb_response *grpc_grpclb_response_parse(gpr_slice encoded_response) {
+  bool status;
+  pb_istream_t stream =
+      pb_istream_from_buffer(GPR_SLICE_START_PTR(encoded_response),
+                             GPR_SLICE_LENGTH(encoded_response));
+  grpc_grpclb_response *res = gpr_malloc(sizeof(grpc_grpclb_response));
+  memset(res, 0, sizeof(*res));
+  status = pb_decode(&stream, grpc_lb_v0_LoadBalanceResponse_fields, res);
+  GPR_ASSERT(status == true);
+  return res;
+}
+
+grpc_grpclb_serverlist *grpc_grpclb_response_parse_serverlist(
+    gpr_slice encoded_response) {
+  grpc_grpclb_serverlist *sl = gpr_malloc(sizeof(grpc_grpclb_serverlist));
+  bool status;
+  decode_serverlist_arg arg;
+  pb_istream_t stream =
+      pb_istream_from_buffer(GPR_SLICE_START_PTR(encoded_response),
+                             GPR_SLICE_LENGTH(encoded_response));
+  pb_istream_t stream_at_start = stream;
+  grpc_grpclb_response *res = gpr_malloc(sizeof(grpc_grpclb_response));
+  memset(res, 0, sizeof(*res));
+  memset(&arg, 0, sizeof(decode_serverlist_arg));
+
+  res->server_list.servers.funcs.decode = decode_serverlist;
+  res->server_list.servers.arg = &arg;
+  arg.first_pass = 1;
+  status = pb_decode(&stream, grpc_lb_v0_LoadBalanceResponse_fields, res);
+  GPR_ASSERT(status == true);
+  GPR_ASSERT(arg.num_servers > 0);
+
+  arg.first_pass = 0;
+  status =
+      pb_decode(&stream_at_start, grpc_lb_v0_LoadBalanceResponse_fields, res);
+  GPR_ASSERT(status == true);
+  GPR_ASSERT(arg.servers != NULL);
+
+  sl->num_servers = arg.num_servers;
+  sl->servers = arg.servers;
+  if (res->server_list.has_expiration_interval) {
+    sl->expiration_interval = res->server_list.expiration_interval;
+  }
+  grpc_grpclb_response_destroy(res);
+  return sl;
+}
+
+void grpc_grpclb_destroy_serverlist(grpc_grpclb_serverlist *serverlist) {
+  size_t i;
+  for (i = 0; i < serverlist->num_servers; i++) {
+    gpr_free(serverlist->servers[i]);
+  }
+  gpr_free(serverlist->servers);
+  gpr_free(serverlist);
+}
+
+void grpc_grpclb_response_destroy(grpc_grpclb_response *response) {
+  gpr_free(response);
+}
diff --git a/src/core/client_config/lb_policies/load_balancer_api.h b/src/core/client_config/lb_policies/load_balancer_api.h
new file mode 100644
index 0000000..4dbe1d6
--- /dev/null
+++ b/src/core/client_config/lb_policies/load_balancer_api.h
@@ -0,0 +1,85 @@
+/*
+ *
+ * Copyright 2016, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef GRPC_INTERNAL_CORE_CLIENT_CONFIG_LB_POLICIES_LOAD_BALANCER_API_H
+#define GRPC_INTERNAL_CORE_CLIENT_CONFIG_LB_POLICIES_LOAD_BALANCER_API_H
+
+#include <grpc/support/slice_buffer.h>
+
+#include "src/core/client_config/lb_policy_factory.h"
+#include "src/core/proto/grpc/lb/v0/load_balancer.pb.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define GRPC_GRPCLB_SERVICE_NAME_MAX_LENGTH 128
+
+typedef grpc_lb_v0_LoadBalanceRequest grpc_grpclb_request;
+typedef grpc_lb_v0_LoadBalanceResponse grpc_grpclb_response;
+typedef grpc_lb_v0_Server grpc_grpclb_server;
+typedef grpc_lb_v0_Duration grpc_grpclb_duration;
+typedef struct grpc_grpclb_serverlist {
+  grpc_grpclb_server **servers;
+  size_t num_servers;
+  grpc_grpclb_duration expiration_interval;
+} grpc_grpclb_serverlist;
+
+/** Create a request for a gRPC LB service under \a lb_service_name */
+grpc_grpclb_request *grpc_grpclb_request_create(const char *lb_service_name);
+
+/** Protocol Buffers v3-encode \a request */
+gpr_slice grpc_grpclb_request_encode(const grpc_grpclb_request *request);
+
+/** Destroy \a request */
+void grpc_grpclb_request_destroy(grpc_grpclb_request *request);
+
+/** Parse (ie, decode) the bytes in \a encoded_response as a \a
+ * grpc_grpclb_response */
+grpc_grpclb_response *grpc_grpclb_response_parse(gpr_slice encoded_response);
+
+/** Destroy \a serverlist */
+void grpc_grpclb_destroy_serverlist(grpc_grpclb_serverlist *serverlist);
+
+/** Parse the list of servers from an encoded \a grpc_grpclb_response */
+grpc_grpclb_serverlist *grpc_grpclb_response_parse_serverlist(
+    gpr_slice encoded_response);
+
+/** Destroy \a response */
+void grpc_grpclb_response_destroy(grpc_grpclb_response *response);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* GRPC_INTERNAL_CORE_CLIENT_CONFIG_LB_POLICIES_LOAD_BALANCER_API_H */
diff --git a/src/core/client_config/lb_policies/pick_first.c b/src/core/client_config/lb_policies/pick_first.c
index 459bbeb..81167b3 100644
--- a/src/core/client_config/lb_policies/pick_first.c
+++ b/src/core/client_config/lb_policies/pick_first.c
@@ -31,8 +31,8 @@
  *
  */
 
-#include "src/core/client_config/lb_policy_factory.h"
 #include "src/core/client_config/lb_policies/pick_first.h"
+#include "src/core/client_config/lb_policy_factory.h"
 
 #include <string.h>
 
@@ -119,7 +119,7 @@
   while (pp != NULL) {
     pending_pick *next = pp->next;
     *pp->target = NULL;
-    grpc_pollset_set_del_pollset(exec_ctx, &p->base.interested_parties,
+    grpc_pollset_set_del_pollset(exec_ctx, p->base.interested_parties,
                                  pp->pollset);
     grpc_exec_ctx_enqueue(exec_ctx, pp->on_complete, true, NULL);
     gpr_free(pp);
@@ -137,7 +137,7 @@
   while (pp != NULL) {
     pending_pick *next = pp->next;
     if (pp->target == target) {
-      grpc_pollset_set_del_pollset(exec_ctx, &p->base.interested_parties,
+      grpc_pollset_set_del_pollset(exec_ctx, p->base.interested_parties,
                                    pp->pollset);
       *target = NULL;
       grpc_exec_ctx_enqueue(exec_ctx, pp->on_complete, false, NULL);
@@ -158,7 +158,7 @@
   GRPC_LB_POLICY_WEAK_REF(&p->base, "pick_first_connectivity");
   grpc_subchannel_notify_on_state_change(
       exec_ctx, p->subchannels[p->checking_subchannel],
-      &p->base.interested_parties, &p->checking_connectivity,
+      p->base.interested_parties, &p->checking_connectivity,
       &p->connectivity_changed);
 }
 
@@ -195,8 +195,7 @@
     if (!p->started_picking) {
       start_picking(exec_ctx, p);
     }
-    grpc_pollset_set_add_pollset(exec_ctx, &p->base.interested_parties,
-                                 pollset);
+    grpc_pollset_set_add_pollset(exec_ctx, p->base.interested_parties, pollset);
     pp = gpr_malloc(sizeof(*pp));
     pp->next = p->pending_picks;
     pp->pollset = pollset;
@@ -253,7 +252,7 @@
                                 p->checking_connectivity, "selected_changed");
     if (p->checking_connectivity != GRPC_CHANNEL_FATAL_FAILURE) {
       grpc_connected_subchannel_notify_on_state_change(
-          exec_ctx, selected, &p->base.interested_parties,
+          exec_ctx, selected, p->base.interested_parties,
           &p->checking_connectivity, &p->connectivity_changed);
     } else {
       GRPC_LB_POLICY_WEAK_UNREF(exec_ctx, &p->base, "pick_first_connectivity");
@@ -278,13 +277,13 @@
         while ((pp = p->pending_picks)) {
           p->pending_picks = pp->next;
           *pp->target = selected;
-          grpc_pollset_set_del_pollset(exec_ctx, &p->base.interested_parties,
+          grpc_pollset_set_del_pollset(exec_ctx, p->base.interested_parties,
                                        pp->pollset);
           grpc_exec_ctx_enqueue(exec_ctx, pp->on_complete, true, NULL);
           gpr_free(pp);
         }
         grpc_connected_subchannel_notify_on_state_change(
-            exec_ctx, selected, &p->base.interested_parties,
+            exec_ctx, selected, p->base.interested_parties,
             &p->checking_connectivity, &p->connectivity_changed);
         break;
       case GRPC_CHANNEL_TRANSIENT_FAILURE:
@@ -298,7 +297,7 @@
         if (p->checking_connectivity == GRPC_CHANNEL_TRANSIENT_FAILURE) {
           grpc_subchannel_notify_on_state_change(
               exec_ctx, p->subchannels[p->checking_subchannel],
-              &p->base.interested_parties, &p->checking_connectivity,
+              p->base.interested_parties, &p->checking_connectivity,
               &p->connectivity_changed);
         } else {
           goto loop;
@@ -311,7 +310,7 @@
                                     "connecting_changed");
         grpc_subchannel_notify_on_state_change(
             exec_ctx, p->subchannels[p->checking_subchannel],
-            &p->base.interested_parties, &p->checking_connectivity,
+            p->base.interested_parties, &p->checking_connectivity,
             &p->connectivity_changed);
         break;
       case GRPC_CHANNEL_FATAL_FAILURE:
diff --git a/src/core/client_config/lb_policies/round_robin.c b/src/core/client_config/lb_policies/round_robin.c
index b1171c4..98d9acc 100644
--- a/src/core/client_config/lb_policies/round_robin.c
+++ b/src/core/client_config/lb_policies/round_robin.c
@@ -260,7 +260,7 @@
   while (pp != NULL) {
     pending_pick *next = pp->next;
     if (pp->target == target) {
-      grpc_pollset_set_del_pollset(exec_ctx, &p->base.interested_parties,
+      grpc_pollset_set_del_pollset(exec_ctx, p->base.interested_parties,
                                    pp->pollset);
       *target = NULL;
       grpc_exec_ctx_enqueue(exec_ctx, pp->on_complete, false, NULL);
@@ -285,7 +285,7 @@
     subchannel_data *sd = p->subchannels[i];
     sd->connectivity_state = GRPC_CHANNEL_IDLE;
     grpc_subchannel_notify_on_state_change(
-        exec_ctx, sd->subchannel, &p->base.interested_parties,
+        exec_ctx, sd->subchannel, p->base.interested_parties,
         &sd->connectivity_state, &sd->connectivity_changed_closure);
     GRPC_LB_POLICY_WEAK_REF(&p->base, "round_robin_connectivity");
   }
@@ -322,8 +322,7 @@
     if (!p->started_picking) {
       start_picking(exec_ctx, p);
     }
-    grpc_pollset_set_add_pollset(exec_ctx, &p->base.interested_parties,
-                                 pollset);
+    grpc_pollset_set_add_pollset(exec_ctx, p->base.interested_parties, pollset);
     pp = gpr_malloc(sizeof(*pp));
     pp->next = p->pending_picks;
     pp->pollset = pollset;
@@ -374,13 +373,13 @@
                     "[RR CONN CHANGED] TARGET <-- SUBCHANNEL %p (NODE %p)",
                     selected->subchannel, selected);
           }
-          grpc_pollset_set_del_pollset(exec_ctx, &p->base.interested_parties,
+          grpc_pollset_set_del_pollset(exec_ctx, p->base.interested_parties,
                                        pp->pollset);
           grpc_exec_ctx_enqueue(exec_ctx, pp->on_complete, true, NULL);
           gpr_free(pp);
         }
         grpc_subchannel_notify_on_state_change(
-            exec_ctx, sd->subchannel, &p->base.interested_parties,
+            exec_ctx, sd->subchannel, p->base.interested_parties,
             &sd->connectivity_state, &sd->connectivity_changed_closure);
         break;
       case GRPC_CHANNEL_CONNECTING:
@@ -389,13 +388,13 @@
                                     sd->connectivity_state,
                                     "connecting_changed");
         grpc_subchannel_notify_on_state_change(
-            exec_ctx, sd->subchannel, &p->base.interested_parties,
+            exec_ctx, sd->subchannel, p->base.interested_parties,
             &sd->connectivity_state, &sd->connectivity_changed_closure);
         break;
       case GRPC_CHANNEL_TRANSIENT_FAILURE:
         /* renew state notification */
         grpc_subchannel_notify_on_state_change(
-            exec_ctx, sd->subchannel, &p->base.interested_parties,
+            exec_ctx, sd->subchannel, p->base.interested_parties,
             &sd->connectivity_state, &sd->connectivity_changed_closure);
 
         /* remove from ready list if still present */
diff --git a/src/core/client_config/lb_policy.c b/src/core/client_config/lb_policy.c
index d4672f6..0d8b007 100644
--- a/src/core/client_config/lb_policy.c
+++ b/src/core/client_config/lb_policy.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -39,7 +39,7 @@
                          const grpc_lb_policy_vtable *vtable) {
   policy->vtable = vtable;
   gpr_atm_no_barrier_store(&policy->ref_pair, 1 << WEAK_REF_BITS);
-  grpc_pollset_set_init(&policy->interested_parties);
+  policy->interested_parties = grpc_pollset_set_create();
 }
 
 #ifdef GRPC_LB_POLICY_REFCOUNT_DEBUG
@@ -93,7 +93,7 @@
   gpr_atm old_val =
       ref_mutate(policy, -(gpr_atm)1, 1 REF_MUTATE_PASS_ARGS("WEAK_UNREF"));
   if (old_val == 1) {
-    grpc_pollset_set_destroy(&policy->interested_parties);
+    grpc_pollset_set_destroy(policy->interested_parties);
     policy->vtable->destroy(exec_ctx, policy);
   }
 }
diff --git a/src/core/client_config/lb_policy.h b/src/core/client_config/lb_policy.h
index db5238c..3457390 100644
--- a/src/core/client_config/lb_policy.h
+++ b/src/core/client_config/lb_policy.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -48,7 +48,8 @@
 struct grpc_lb_policy {
   const grpc_lb_policy_vtable *vtable;
   gpr_atm ref_pair;
-  grpc_pollset_set interested_parties;
+  /* owned pointer to interested parties in load balancing decisions */
+  grpc_pollset_set *interested_parties;
 };
 
 struct grpc_lb_policy_vtable {
diff --git a/src/core/client_config/subchannel.c b/src/core/client_config/subchannel.c
index 6599c75..d91dd11 100644
--- a/src/core/client_config/subchannel.c
+++ b/src/core/client_config/subchannel.c
@@ -108,7 +108,7 @@
 
   /** pollset_set tracking who's interested in a connection
       being setup */
-  grpc_pollset_set pollset_set;
+  grpc_pollset_set *pollset_set;
 
   /** active connection, or null; of type grpc_connected_subchannel */
   gpr_atm connected_subchannel;
@@ -209,7 +209,7 @@
   gpr_slice_unref(c->initial_connect_string);
   grpc_connectivity_state_destroy(exec_ctx, &c->state_tracker);
   grpc_connector_unref(exec_ctx, c->connector);
-  grpc_pollset_set_destroy(&c->pollset_set);
+  grpc_pollset_set_destroy(c->pollset_set);
   grpc_subchannel_key_destroy(exec_ctx, c->key);
   gpr_free(c);
 }
@@ -326,7 +326,7 @@
   }
   c->addr = gpr_malloc(args->addr_len);
   memcpy(c->addr, args->addr, args->addr_len);
-  grpc_pollset_set_init(&c->pollset_set);
+  c->pollset_set = grpc_pollset_set_create();
   c->addr_len = args->addr_len;
   grpc_set_initial_connect_string(&c->addr, &c->addr_len,
                                   &c->initial_connect_string);
@@ -345,7 +345,7 @@
 static void continue_connect(grpc_exec_ctx *exec_ctx, grpc_subchannel *c) {
   grpc_connect_in_args args;
 
-  args.interested_parties = &c->pollset_set;
+  args.interested_parties = c->pollset_set;
   args.addr = c->addr;
   args.addr_len = c->addr_len;
   args.deadline = compute_connect_deadline(c);
@@ -379,7 +379,7 @@
   external_state_watcher *w = arg;
   grpc_closure *follow_up = w->notify;
   if (w->pollset_set != NULL) {
-    grpc_pollset_set_del_pollset_set(exec_ctx, &w->subchannel->pollset_set,
+    grpc_pollset_set_del_pollset_set(exec_ctx, w->subchannel->pollset_set,
                                      w->pollset_set);
   }
   gpr_mu_lock(&w->subchannel->mu);
@@ -395,7 +395,6 @@
     grpc_exec_ctx *exec_ctx, grpc_subchannel *c,
     grpc_pollset_set *interested_parties, grpc_connectivity_state *state,
     grpc_closure *notify) {
-  int do_connect = 0;
   external_state_watcher *w;
 
   if (state == NULL) {
@@ -415,7 +414,7 @@
     w->notify = notify;
     grpc_closure_init(&w->closure, on_external_state_watcher_done, w);
     if (interested_parties != NULL) {
-      grpc_pollset_set_add_pollset_set(exec_ctx, &c->pollset_set,
+      grpc_pollset_set_add_pollset_set(exec_ctx, c->pollset_set,
                                        interested_parties);
     }
     GRPC_SUBCHANNEL_WEAK_REF(c, "external_state_watcher");
@@ -425,17 +424,13 @@
     w->next->prev = w->prev->next = w;
     if (grpc_connectivity_state_notify_on_state_change(
             exec_ctx, &c->state_tracker, state, &w->closure)) {
-      do_connect = 1;
       c->connecting = 1;
       /* released by connection */
       GRPC_SUBCHANNEL_WEAK_REF(c, "connecting");
+      start_connect(exec_ctx, c);
     }
     gpr_mu_unlock(&c->mu);
   }
-
-  if (do_connect) {
-    start_connect(exec_ctx, c);
-  }
 }
 
 void grpc_connected_subchannel_process_transport_op(
@@ -573,7 +568,7 @@
   GRPC_SUBCHANNEL_WEAK_REF(c, "state_watcher");
   GRPC_SUBCHANNEL_WEAK_UNREF(exec_ctx, c, "connecting");
   grpc_connected_subchannel_notify_on_state_change(
-      exec_ctx, con, &c->pollset_set, &sw_subchannel->connectivity_state,
+      exec_ctx, con, c->pollset_set, &sw_subchannel->connectivity_state,
       &sw_subchannel->closure);
 
   /* signal completion */
@@ -635,11 +630,12 @@
   if (c->disconnected) {
     iomgr_success = 0;
   }
-  gpr_mu_unlock(&c->mu);
   if (iomgr_success) {
     update_reconnect_parameters(c);
     continue_connect(exec_ctx, c);
+    gpr_mu_unlock(&c->mu);
   } else {
+    gpr_mu_unlock(&c->mu);
     GRPC_SUBCHANNEL_WEAK_UNREF(exec_ctx, c, "connecting");
   }
 }
diff --git a/src/core/client_config/subchannel_index.c b/src/core/client_config/subchannel_index.c
index f78a7fd..3f94899 100644
--- a/src/core/client_config/subchannel_index.c
+++ b/src/core/client_config/subchannel_index.c
@@ -149,11 +149,13 @@
 void grpc_subchannel_index_init(void) {
   g_subchannel_index = gpr_avl_create(&subchannel_avl_vtable);
   gpr_mu_init(&g_mu);
+  gpr_tls_init(&subchannel_index_exec_ctx);
 }
 
 void grpc_subchannel_index_shutdown(void) {
   gpr_mu_destroy(&g_mu);
   gpr_avl_unref(g_subchannel_index);
+  gpr_tls_destroy(&subchannel_index_exec_ctx);
 }
 
 grpc_subchannel *grpc_subchannel_index_find(grpc_exec_ctx *exec_ctx,
diff --git a/src/core/compression/algorithm.c b/src/core/compression/compression_algorithm.c
similarity index 100%
rename from src/core/compression/algorithm.c
rename to src/core/compression/compression_algorithm.c
diff --git a/src/core/httpcli/httpcli.c b/src/core/httpcli/httpcli.c
index 71237bb..1219c44 100644
--- a/src/core/httpcli/httpcli.c
+++ b/src/core/httpcli/httpcli.c
@@ -31,21 +31,23 @@
  *
  */
 
-#include "src/core/iomgr/sockaddr.h"
 #include "src/core/httpcli/httpcli.h"
+#include "src/core/iomgr/sockaddr.h"
 
 #include <string.h>
 
-#include "src/core/iomgr/endpoint.h"
-#include "src/core/iomgr/resolve_address.h"
-#include "src/core/iomgr/tcp_client.h"
-#include "src/core/httpcli/format_request.h"
-#include "src/core/httpcli/parser.h"
-#include "src/core/support/string.h"
 #include <grpc/support/alloc.h>
 #include <grpc/support/log.h>
 #include <grpc/support/string_util.h>
 
+#include "src/core/httpcli/format_request.h"
+#include "src/core/httpcli/parser.h"
+#include "src/core/iomgr/endpoint.h"
+#include "src/core/iomgr/iomgr_internal.h"
+#include "src/core/iomgr/resolve_address.h"
+#include "src/core/iomgr/tcp_client.h"
+#include "src/core/support/string.h"
+
 typedef struct {
   gpr_slice request_text;
   grpc_httpcli_parser parser;
@@ -84,18 +86,18 @@
                                                         plaintext_handshake};
 
 void grpc_httpcli_context_init(grpc_httpcli_context *context) {
-  grpc_pollset_set_init(&context->pollset_set);
+  context->pollset_set = grpc_pollset_set_create();
 }
 
 void grpc_httpcli_context_destroy(grpc_httpcli_context *context) {
-  grpc_pollset_set_destroy(&context->pollset_set);
+  grpc_pollset_set_destroy(context->pollset_set);
 }
 
 static void next_address(grpc_exec_ctx *exec_ctx, internal_request *req);
 
 static void finish(grpc_exec_ctx *exec_ctx, internal_request *req,
                    int success) {
-  grpc_pollset_set_del_pollset(exec_ctx, &req->context->pollset_set,
+  grpc_pollset_set_del_pollset(exec_ctx, req->context->pollset_set,
                                req->pollset);
   req->on_response(exec_ctx, req->user_data, success ? &req->parser.r : NULL);
   grpc_httpcli_parser_destroy(&req->parser);
@@ -197,7 +199,7 @@
   addr = &req->addresses->addrs[req->next_address++];
   grpc_closure_init(&req->connected, on_connected, req);
   grpc_tcp_client_connect(
-      exec_ctx, &req->connected, &req->ep, &req->context->pollset_set,
+      exec_ctx, &req->connected, &req->ep, req->context->pollset_set,
       (struct sockaddr *)&addr->addr, addr->len, req->deadline);
 }
 
@@ -237,7 +239,7 @@
   req->host = gpr_strdup(request->host);
   req->ssl_host_override = gpr_strdup(request->ssl_host_override);
 
-  grpc_pollset_set_add_pollset(exec_ctx, &req->context->pollset_set,
+  grpc_pollset_set_add_pollset(exec_ctx, req->context->pollset_set,
                                req->pollset);
   grpc_resolve_address(request->host, req->handshaker->default_port,
                        on_resolved, req);
diff --git a/src/core/httpcli/httpcli.h b/src/core/httpcli/httpcli.h
index 30875d7..c9cd987 100644
--- a/src/core/httpcli/httpcli.h
+++ b/src/core/httpcli/httpcli.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -39,6 +39,7 @@
 #include <grpc/support/time.h>
 
 #include "src/core/iomgr/endpoint.h"
+#include "src/core/iomgr/iomgr_internal.h"
 #include "src/core/iomgr/pollset_set.h"
 
 /* User agent this library reports */
@@ -56,7 +57,7 @@
    TODO(ctiller): allow caching and capturing multiple requests for the
                   same content and combining them */
 typedef struct grpc_httpcli_context {
-  grpc_pollset_set pollset_set;
+  grpc_pollset_set *pollset_set;
 } grpc_httpcli_context;
 
 typedef struct {
diff --git a/src/core/httpcli/httpcli_security_connector.c b/src/core/httpcli/httpcli_security_connector.c
index 41ad1de..156961a 100644
--- a/src/core/httpcli/httpcli_security_connector.c
+++ b/src/core/httpcli/httpcli_security_connector.c
@@ -59,7 +59,7 @@
 }
 
 static void httpcli_ssl_do_handshake(grpc_exec_ctx *exec_ctx,
-                                     grpc_security_connector *sc,
+                                     grpc_channel_security_connector *sc,
                                      grpc_endpoint *nonsecure_endpoint,
                                      grpc_security_handshake_done_cb cb,
                                      void *user_data) {
@@ -78,8 +78,8 @@
             tsi_result_to_string(result));
     cb(exec_ctx, user_data, GRPC_SECURITY_ERROR, NULL, NULL);
   } else {
-    grpc_do_security_handshake(exec_ctx, handshaker, sc, nonsecure_endpoint, cb,
-                               user_data);
+    grpc_do_security_handshake(exec_ctx, handshaker, &sc->base, true,
+                               nonsecure_endpoint, cb, user_data);
   }
 }
 
@@ -103,7 +103,7 @@
 }
 
 static grpc_security_connector_vtable httpcli_ssl_vtable = {
-    httpcli_ssl_destroy, httpcli_ssl_do_handshake, httpcli_ssl_check_peer};
+    httpcli_ssl_destroy, httpcli_ssl_check_peer};
 
 static grpc_security_status httpcli_ssl_channel_security_connector_create(
     const unsigned char *pem_root_certs, size_t pem_root_certs_size,
@@ -121,7 +121,6 @@
   memset(c, 0, sizeof(grpc_httpcli_ssl_channel_security_connector));
 
   gpr_ref_init(&c->base.base.refcount, 1);
-  c->base.base.is_client_side = 1;
   c->base.base.vtable = &httpcli_ssl_vtable;
   if (secure_peer_name != NULL) {
     c->secure_peer_name = gpr_strdup(secure_peer_name);
@@ -136,6 +135,7 @@
     *sc = NULL;
     return GRPC_SECURITY_ERROR;
   }
+  c->base.do_handshake = httpcli_ssl_do_handshake;
   *sc = &c->base;
   return GRPC_SECURITY_OK;
 }
@@ -180,8 +180,8 @@
   GPR_ASSERT(httpcli_ssl_channel_security_connector_create(
                  pem_root_certs, pem_root_certs_size, host, &sc) ==
              GRPC_SECURITY_OK);
-  grpc_security_connector_do_handshake(exec_ctx, &sc->base, tcp,
-                                       on_secure_transport_setup_done, c);
+  grpc_channel_security_connector_do_handshake(
+      exec_ctx, sc, tcp, on_secure_transport_setup_done, c);
   GRPC_SECURITY_CONNECTOR_UNREF(&sc->base, "httpcli");
 }
 
diff --git a/src/core/iomgr/fd_posix.c b/src/core/iomgr/fd_posix.c
index 85eadd7..4ba7c5d 100644
--- a/src/core/iomgr/fd_posix.c
+++ b/src/core/iomgr/fd_posix.c
@@ -46,6 +46,8 @@
 #include <grpc/support/string_util.h>
 #include <grpc/support/useful.h>
 
+#include "src/core/iomgr/pollset_posix.h"
+
 #define CLOSURE_NOT_READY ((grpc_closure *)0)
 #define CLOSURE_READY ((grpc_closure *)1)
 
@@ -175,11 +177,11 @@
 }
 
 static void pollset_kick_locked(grpc_fd_watcher *watcher) {
-  gpr_mu_lock(GRPC_POLLSET_MU(watcher->pollset));
+  gpr_mu_lock(&watcher->pollset->mu);
   GPR_ASSERT(watcher->worker);
   grpc_pollset_kick_ext(watcher->pollset, watcher->worker,
                         GRPC_POLLSET_REEVALUATE_POLLING_ON_WAKEUP);
-  gpr_mu_unlock(GRPC_POLLSET_MU(watcher->pollset));
+  gpr_mu_unlock(&watcher->pollset->mu);
 }
 
 static void maybe_wake_one_watcher_locked(grpc_fd *fd) {
diff --git a/src/core/iomgr/iocp_windows.c b/src/core/iomgr/iocp_windows.c
index 759340e..8077297 100644
--- a/src/core/iomgr/iocp_windows.c
+++ b/src/core/iomgr/iocp_windows.c
@@ -42,7 +42,7 @@
 #include <grpc/support/alloc.h>
 #include <grpc/support/thd.h>
 
-#include "src/core/iomgr/timer_internal.h"
+#include "src/core/iomgr/timer.h"
 #include "src/core/iomgr/iocp_windows.h"
 #include "src/core/iomgr/iomgr_internal.h"
 #include "src/core/iomgr/socket_windows.h"
diff --git a/src/core/iomgr/iomgr.c b/src/core/iomgr/iomgr.c
index 212ce55..9c89c2c 100644
--- a/src/core/iomgr/iomgr.c
+++ b/src/core/iomgr/iomgr.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -41,9 +41,11 @@
 #include <grpc/support/string_util.h>
 #include <grpc/support/sync.h>
 #include <grpc/support/thd.h>
+#include <grpc/support/useful.h>
 
 #include "src/core/iomgr/iomgr_internal.h"
-#include "src/core/iomgr/timer_internal.h"
+#include "src/core/iomgr/timer.h"
+#include "src/core/support/env.h"
 #include "src/core/support/string.h"
 
 static gpr_mu g_mu;
@@ -116,6 +118,9 @@
                     "memory leaks are likely",
                     count_objects());
             dump_objects("LEAKED");
+            if (grpc_iomgr_abort_on_leaks()) {
+              abort();
+            }
           }
           break;
         }
@@ -154,3 +159,14 @@
   gpr_mu_unlock(&g_mu);
   gpr_free(obj->name);
 }
+
+bool grpc_iomgr_abort_on_leaks(void) {
+  char *env = gpr_getenv("GRPC_ABORT_ON_LEAKS");
+  if (env == NULL) return false;
+  static const char *truthy[] = {"yes",  "Yes",  "YES", "true",
+                                 "True", "TRUE", "1"};
+  for (size_t i = 0; i < GPR_ARRAY_SIZE(truthy); i++) {
+    if (0 == strcmp(env, truthy[i])) return true;
+  }
+  return false;
+}
diff --git a/src/core/iomgr/iomgr_internal.h b/src/core/iomgr/iomgr_internal.h
index e372c18..ac2c46e 100644
--- a/src/core/iomgr/iomgr_internal.h
+++ b/src/core/iomgr/iomgr_internal.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -34,6 +34,8 @@
 #ifndef GRPC_INTERNAL_CORE_IOMGR_IOMGR_INTERNAL_H
 #define GRPC_INTERNAL_CORE_IOMGR_IOMGR_INTERNAL_H
 
+#include <stdbool.h>
+
 #include "src/core/iomgr/iomgr.h"
 #include <grpc/support/sync.h>
 
@@ -55,4 +57,6 @@
 /** tear down all platform specific global iomgr structures */
 void grpc_iomgr_platform_shutdown(void);
 
+bool grpc_iomgr_abort_on_leaks(void);
+
 #endif /* GRPC_INTERNAL_CORE_IOMGR_IOMGR_INTERNAL_H */
diff --git a/src/core/iomgr/pollset.h b/src/core/iomgr/pollset.h
index c6b0214..92a0374 100644
--- a/src/core/iomgr/pollset.h
+++ b/src/core/iomgr/pollset.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -35,8 +35,11 @@
 #define GRPC_INTERNAL_CORE_IOMGR_POLLSET_H
 
 #include <grpc/support/port_platform.h>
+#include <grpc/support/sync.h>
 #include <grpc/support/time.h>
 
+#include "src/core/iomgr/exec_ctx.h"
+
 #define GRPC_POLLSET_KICK_BROADCAST ((grpc_pollset_worker *)1)
 
 /* A grpc_pollset is a set of file descriptors that a higher level item is
@@ -46,15 +49,11 @@
     - a completion queue might keep a pollset with an entry for each transport
       that is servicing a call that it's tracking */
 
-#ifdef GPR_POSIX_SOCKET
-#include "src/core/iomgr/pollset_posix.h"
-#endif
+typedef struct grpc_pollset grpc_pollset;
+typedef struct grpc_pollset_worker grpc_pollset_worker;
 
-#ifdef GPR_WIN32
-#include "src/core/iomgr/pollset_windows.h"
-#endif
-
-void grpc_pollset_init(grpc_pollset *pollset);
+size_t grpc_pollset_size(void);
+void grpc_pollset_init(grpc_pollset *pollset, gpr_mu **mu);
 /* Begin shutting down the pollset, and call closure when done.
  * GRPC_POLLSET_MU(pollset) must be held */
 void grpc_pollset_shutdown(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset,
@@ -83,7 +82,7 @@
    pollset
    lock */
 void grpc_pollset_work(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset,
-                       grpc_pollset_worker *worker, gpr_timespec now,
+                       grpc_pollset_worker **worker, gpr_timespec now,
                        gpr_timespec deadline);
 
 /* Break one polling thread out of polling work for this pollset.
diff --git a/src/core/iomgr/pollset_multipoller_with_epoll.c b/src/core/iomgr/pollset_multipoller_with_epoll.c
index 4acae2b..2e0f27f 100644
--- a/src/core/iomgr/pollset_multipoller_with_epoll.c
+++ b/src/core/iomgr/pollset_multipoller_with_epoll.c
@@ -45,6 +45,7 @@
 #include <grpc/support/log.h>
 #include <grpc/support/useful.h>
 #include "src/core/iomgr/fd_posix.h"
+#include "src/core/iomgr/pollset_posix.h"
 #include "src/core/profiling/timers.h"
 #include "src/core/support/block_annotate.h"
 
diff --git a/src/core/iomgr/pollset_multipoller_with_poll_posix.c b/src/core/iomgr/pollset_multipoller_with_poll_posix.c
index 809f8f3..4dddfff 100644
--- a/src/core/iomgr/pollset_multipoller_with_poll_posix.c
+++ b/src/core/iomgr/pollset_multipoller_with_poll_posix.c
@@ -42,13 +42,15 @@
 #include <stdlib.h>
 #include <string.h>
 
-#include "src/core/iomgr/fd_posix.h"
-#include "src/core/iomgr/iomgr_internal.h"
-#include "src/core/support/block_annotate.h"
 #include <grpc/support/alloc.h>
 #include <grpc/support/log.h>
 #include <grpc/support/useful.h>
 
+#include "src/core/iomgr/fd_posix.h"
+#include "src/core/iomgr/iomgr_internal.h"
+#include "src/core/iomgr/pollset_posix.h"
+#include "src/core/support/block_annotate.h"
+
 typedef struct {
   /* all polled fds */
   size_t fd_count;
diff --git a/src/core/iomgr/pollset_posix.c b/src/core/iomgr/pollset_posix.c
index 19ee665..e895a77 100644
--- a/src/core/iomgr/pollset_posix.c
+++ b/src/core/iomgr/pollset_posix.c
@@ -42,17 +42,16 @@
 #include <string.h>
 #include <unistd.h>
 
-#include "src/core/iomgr/timer_internal.h"
-#include "src/core/iomgr/fd_posix.h"
-#include "src/core/iomgr/iomgr_internal.h"
-#include "src/core/iomgr/socket_utils_posix.h"
-#include "src/core/profiling/timers.h"
-#include "src/core/support/block_annotate.h"
 #include <grpc/support/alloc.h>
 #include <grpc/support/log.h>
 #include <grpc/support/thd.h>
 #include <grpc/support/tls.h>
 #include <grpc/support/useful.h>
+#include "src/core/iomgr/fd_posix.h"
+#include "src/core/iomgr/iomgr_internal.h"
+#include "src/core/iomgr/socket_utils_posix.h"
+#include "src/core/profiling/timers.h"
+#include "src/core/support/block_annotate.h"
 
 GPR_TLS_DECL(g_current_thread_poller);
 GPR_TLS_DECL(g_current_thread_worker);
@@ -98,6 +97,8 @@
   worker->prev->next = worker->next->prev = worker;
 }
 
+size_t grpc_pollset_size(void) { return sizeof(grpc_pollset); }
+
 void grpc_pollset_kick_ext(grpc_pollset *p,
                            grpc_pollset_worker *specific_worker,
                            uint32_t flags) {
@@ -187,8 +188,9 @@
 
 static void become_basic_pollset(grpc_pollset *pollset, grpc_fd *fd_or_null);
 
-void grpc_pollset_init(grpc_pollset *pollset) {
+void grpc_pollset_init(grpc_pollset *pollset, gpr_mu **mu) {
   gpr_mu_init(&pollset->mu);
+  *mu = &pollset->mu;
   pollset->root_worker.next = pollset->root_worker.prev = &pollset->root_worker;
   pollset->in_flight_cbs = 0;
   pollset->shutting_down = 0;
@@ -205,7 +207,6 @@
   GPR_ASSERT(!grpc_pollset_has_workers(pollset));
   GPR_ASSERT(pollset->idle_jobs.head == pollset->idle_jobs.tail);
   pollset->vtable->destroy(pollset);
-  gpr_mu_destroy(&pollset->mu);
   while (pollset->local_wakeup_cache) {
     grpc_cached_wakeup_fd *next = pollset->local_wakeup_cache->next;
     grpc_wakeup_fd_destroy(&pollset->local_wakeup_cache->fd);
@@ -247,8 +248,11 @@
 }
 
 void grpc_pollset_work(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset,
-                       grpc_pollset_worker *worker, gpr_timespec now,
+                       grpc_pollset_worker **worker_hdl, gpr_timespec now,
                        gpr_timespec deadline) {
+  grpc_pollset_worker worker;
+  *worker_hdl = &worker;
+
   /* pollset->mu already held */
   int added_worker = 0;
   int locked = 1;
@@ -256,16 +260,16 @@
   int keep_polling = 0;
   GPR_TIMER_BEGIN("grpc_pollset_work", 0);
   /* this must happen before we (potentially) drop pollset->mu */
-  worker->next = worker->prev = NULL;
-  worker->reevaluate_polling_on_wakeup = 0;
+  worker.next = worker.prev = NULL;
+  worker.reevaluate_polling_on_wakeup = 0;
   if (pollset->local_wakeup_cache != NULL) {
-    worker->wakeup_fd = pollset->local_wakeup_cache;
-    pollset->local_wakeup_cache = worker->wakeup_fd->next;
+    worker.wakeup_fd = pollset->local_wakeup_cache;
+    pollset->local_wakeup_cache = worker.wakeup_fd->next;
   } else {
-    worker->wakeup_fd = gpr_malloc(sizeof(*worker->wakeup_fd));
-    grpc_wakeup_fd_init(&worker->wakeup_fd->fd);
+    worker.wakeup_fd = gpr_malloc(sizeof(*worker.wakeup_fd));
+    grpc_wakeup_fd_init(&worker.wakeup_fd->fd);
   }
-  worker->kicked_specifically = 0;
+  worker.kicked_specifically = 0;
   /* If there's work waiting for the pollset to be idle, and the
      pollset is idle, then do that work */
   if (!grpc_pollset_has_workers(pollset) &&
@@ -274,16 +278,6 @@
     grpc_exec_ctx_enqueue_list(exec_ctx, &pollset->idle_jobs, NULL);
     goto done;
   }
-  /* Check alarms - these are a global resource so we just ping
-     each time through on every pollset.
-     May update deadline to ensure timely wakeups.
-     TODO(ctiller): can this work be localized? */
-  if (grpc_timer_check(exec_ctx, now, &deadline)) {
-    GPR_TIMER_MARK("grpc_pollset_work.alarm_triggered", 0);
-    gpr_mu_unlock(&pollset->mu);
-    locked = 0;
-    goto done;
-  }
   /* If we're shutting down then we don't execute any extended work */
   if (pollset->shutting_down) {
     GPR_TIMER_MARK("grpc_pollset_work.shutting_down", 0);
@@ -304,13 +298,13 @@
     keep_polling = 0;
     if (!pollset->kicked_without_pollers) {
       if (!added_worker) {
-        push_front_worker(pollset, worker);
+        push_front_worker(pollset, &worker);
         added_worker = 1;
-        gpr_tls_set(&g_current_thread_worker, (intptr_t)worker);
+        gpr_tls_set(&g_current_thread_worker, (intptr_t)&worker);
       }
       gpr_tls_set(&g_current_thread_poller, (intptr_t)pollset);
       GPR_TIMER_BEGIN("maybe_work_and_unlock", 0);
-      pollset->vtable->maybe_work_and_unlock(exec_ctx, pollset, worker,
+      pollset->vtable->maybe_work_and_unlock(exec_ctx, pollset, &worker,
                                              deadline, now);
       GPR_TIMER_END("maybe_work_and_unlock", 0);
       locked = 0;
@@ -332,10 +326,10 @@
     /* If we're forced to re-evaluate polling (via grpc_pollset_kick with
        GRPC_POLLSET_REEVALUATE_POLLING_ON_WAKEUP) then we land here and force
        a loop */
-    if (worker->reevaluate_polling_on_wakeup) {
-      worker->reevaluate_polling_on_wakeup = 0;
+    if (worker.reevaluate_polling_on_wakeup) {
+      worker.reevaluate_polling_on_wakeup = 0;
       pollset->kicked_without_pollers = 0;
-      if (queued_work || worker->kicked_specifically) {
+      if (queued_work || worker.kicked_specifically) {
         /* If there's queued work on the list, then set the deadline to be
            immediate so we get back out of the polling loop quickly */
         deadline = gpr_inf_past(GPR_CLOCK_MONOTONIC);
@@ -344,12 +338,12 @@
     }
   }
   if (added_worker) {
-    remove_worker(pollset, worker);
+    remove_worker(pollset, &worker);
     gpr_tls_set(&g_current_thread_worker, 0);
   }
   /* release wakeup fd to the local pool */
-  worker->wakeup_fd->next = pollset->local_wakeup_cache;
-  pollset->local_wakeup_cache = worker->wakeup_fd;
+  worker.wakeup_fd->next = pollset->local_wakeup_cache;
+  pollset->local_wakeup_cache = worker.wakeup_fd;
   /* check shutdown conditions */
   if (pollset->shutting_down) {
     if (grpc_pollset_has_workers(pollset)) {
@@ -371,6 +365,7 @@
       gpr_mu_lock(&pollset->mu);
     }
   }
+  *worker_hdl = NULL;
   GPR_TIMER_END("grpc_pollset_work", 0);
 }
 
diff --git a/src/core/iomgr/pollset_posix.h b/src/core/iomgr/pollset_posix.h
index b34bb09..bbedb66 100644
--- a/src/core/iomgr/pollset_posix.h
+++ b/src/core/iomgr/pollset_posix.h
@@ -37,8 +37,10 @@
 #include <poll.h>
 
 #include <grpc/support/sync.h>
+
 #include "src/core/iomgr/exec_ctx.h"
 #include "src/core/iomgr/iomgr.h"
+#include "src/core/iomgr/pollset.h"
 #include "src/core/iomgr/wakeup_fd_posix.h"
 
 typedef struct grpc_pollset_vtable grpc_pollset_vtable;
@@ -53,15 +55,15 @@
   struct grpc_cached_wakeup_fd *next;
 } grpc_cached_wakeup_fd;
 
-typedef struct grpc_pollset_worker {
+struct grpc_pollset_worker {
   grpc_cached_wakeup_fd *wakeup_fd;
   int reevaluate_polling_on_wakeup;
   int kicked_specifically;
   struct grpc_pollset_worker *next;
   struct grpc_pollset_worker *prev;
-} grpc_pollset_worker;
+};
 
-typedef struct grpc_pollset {
+struct grpc_pollset {
   /* pollsets under posix can mutate representation as fds are added and
      removed.
      For example, we may choose a poll() based implementation on linux for
@@ -81,7 +83,7 @@
   } data;
   /* Local cache of eventfds for workers */
   grpc_cached_wakeup_fd *local_wakeup_cache;
-} grpc_pollset;
+};
 
 struct grpc_pollset_vtable {
   void (*add_fd)(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset,
@@ -93,8 +95,6 @@
   void (*destroy)(grpc_pollset *pollset);
 };
 
-#define GRPC_POLLSET_MU(pollset) (&(pollset)->mu)
-
 /* Add an fd to a pollset */
 void grpc_pollset_add_fd(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset,
                          struct grpc_fd *fd);
@@ -142,6 +142,10 @@
 void grpc_remove_fd_from_all_epoll_sets(int fd);
 
 /* override to allow tests to hook poll() usage */
+/* NOTE: Any changes to grpc_poll_function must take place when the gRPC
+   is certainly not doing any polling anywhere.
+   Otherwise, there might be a race between changing the variable and actually
+   doing a polling operation */
 typedef int (*grpc_poll_function_type)(struct pollfd *, nfds_t, int);
 extern grpc_poll_function_type grpc_poll_function;
 extern grpc_wakeup_fd grpc_global_wakeup_fd;
diff --git a/src/core/iomgr/pollset_set.h b/src/core/iomgr/pollset_set.h
index 09c0443..dddcd83 100644
--- a/src/core/iomgr/pollset_set.h
+++ b/src/core/iomgr/pollset_set.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -41,15 +41,9 @@
    fd's (etc) that have been registered with the set_set to that pollset.
    Registering fd's automatically adds them to all current pollsets. */
 
-#ifdef GPR_POSIX_SOCKET
-#include "src/core/iomgr/pollset_set_posix.h"
-#endif
+typedef struct grpc_pollset_set grpc_pollset_set;
 
-#ifdef GPR_WIN32
-#include "src/core/iomgr/pollset_set_windows.h"
-#endif
-
-void grpc_pollset_set_init(grpc_pollset_set *pollset_set);
+grpc_pollset_set *grpc_pollset_set_create(void);
 void grpc_pollset_set_destroy(grpc_pollset_set *pollset_set);
 void grpc_pollset_set_add_pollset(grpc_exec_ctx *exec_ctx,
                                   grpc_pollset_set *pollset_set,
diff --git a/src/core/iomgr/pollset_set_posix.c b/src/core/iomgr/pollset_set_posix.c
index 4ec9220..9dc9aff 100644
--- a/src/core/iomgr/pollset_set_posix.c
+++ b/src/core/iomgr/pollset_set_posix.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -41,11 +41,30 @@
 #include <grpc/support/alloc.h>
 #include <grpc/support/useful.h>
 
-#include "src/core/iomgr/pollset_set.h"
+#include "src/core/iomgr/pollset_posix.h"
+#include "src/core/iomgr/pollset_set_posix.h"
 
-void grpc_pollset_set_init(grpc_pollset_set *pollset_set) {
+struct grpc_pollset_set {
+  gpr_mu mu;
+
+  size_t pollset_count;
+  size_t pollset_capacity;
+  grpc_pollset **pollsets;
+
+  size_t pollset_set_count;
+  size_t pollset_set_capacity;
+  struct grpc_pollset_set **pollset_sets;
+
+  size_t fd_count;
+  size_t fd_capacity;
+  grpc_fd **fds;
+};
+
+grpc_pollset_set *grpc_pollset_set_create(void) {
+  grpc_pollset_set *pollset_set = gpr_malloc(sizeof(*pollset_set));
   memset(pollset_set, 0, sizeof(*pollset_set));
   gpr_mu_init(&pollset_set->mu);
+  return pollset_set;
 }
 
 void grpc_pollset_set_destroy(grpc_pollset_set *pollset_set) {
@@ -57,6 +76,7 @@
   gpr_free(pollset_set->pollsets);
   gpr_free(pollset_set->pollset_sets);
   gpr_free(pollset_set->fds);
+  gpr_free(pollset_set);
 }
 
 void grpc_pollset_set_add_pollset(grpc_exec_ctx *exec_ctx,
diff --git a/src/core/iomgr/pollset_set_posix.h b/src/core/iomgr/pollset_set_posix.h
index 4820a61..7d1aaf4 100644
--- a/src/core/iomgr/pollset_set_posix.h
+++ b/src/core/iomgr/pollset_set_posix.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -35,23 +35,7 @@
 #define GRPC_INTERNAL_CORE_IOMGR_POLLSET_SET_POSIX_H
 
 #include "src/core/iomgr/fd_posix.h"
-#include "src/core/iomgr/pollset_posix.h"
-
-typedef struct grpc_pollset_set {
-  gpr_mu mu;
-
-  size_t pollset_count;
-  size_t pollset_capacity;
-  grpc_pollset **pollsets;
-
-  size_t pollset_set_count;
-  size_t pollset_set_capacity;
-  struct grpc_pollset_set **pollset_sets;
-
-  size_t fd_count;
-  size_t fd_capacity;
-  grpc_fd **fds;
-} grpc_pollset_set;
+#include "src/core/iomgr/pollset_set.h"
 
 void grpc_pollset_set_add_fd(grpc_exec_ctx *exec_ctx,
                              grpc_pollset_set *pollset_set, grpc_fd *fd);
diff --git a/src/core/iomgr/pollset_set_windows.c b/src/core/iomgr/pollset_set_windows.c
index 157b46e..3b8eca2 100644
--- a/src/core/iomgr/pollset_set_windows.c
+++ b/src/core/iomgr/pollset_set_windows.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -35,9 +35,9 @@
 
 #ifdef GPR_WINSOCK_SOCKET
 
-#include "src/core/iomgr/pollset_set.h"
+#include "src/core/iomgr/pollset_set_windows.h"
 
-void grpc_pollset_set_init(grpc_pollset_set* pollset_set) {}
+grpc_pollset_set* grpc_pollset_set_create(pollset_set) { return NULL; }
 
 void grpc_pollset_set_destroy(grpc_pollset_set* pollset_set) {}
 
diff --git a/src/core/iomgr/pollset_set_windows.h b/src/core/iomgr/pollset_set_windows.h
index cada0d2..9661cd2 100644
--- a/src/core/iomgr/pollset_set_windows.h
+++ b/src/core/iomgr/pollset_set_windows.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -34,6 +34,6 @@
 #ifndef GRPC_INTERNAL_CORE_IOMGR_POLLSET_SET_WINDOWS_H
 #define GRPC_INTERNAL_CORE_IOMGR_POLLSET_SET_WINDOWS_H
 
-typedef struct grpc_pollset_set { void *unused; } grpc_pollset_set;
+#include "src/core/iomgr/pollset_set.h"
 
 #endif /* GRPC_INTERNAL_CORE_IOMGR_POLLSET_WINDOWS_H */
diff --git a/src/core/iomgr/pollset_windows.c b/src/core/iomgr/pollset_windows.c
index 02c6678..c7f30f4 100644
--- a/src/core/iomgr/pollset_windows.c
+++ b/src/core/iomgr/pollset_windows.c
@@ -38,7 +38,6 @@
 #include <grpc/support/log.h>
 #include <grpc/support/thd.h>
 
-#include "src/core/iomgr/timer_internal.h"
 #include "src/core/iomgr/iomgr_internal.h"
 #include "src/core/iomgr/iocp_windows.h"
 #include "src/core/iomgr/pollset.h"
@@ -90,12 +89,15 @@
       worker->links[type].next->links[type].prev = worker;
 }
 
+size_t grpc_pollset_size(void) { return sizeof(grpc_pollset); }
+
 /* There isn't really any such thing as a pollset under Windows, due to the
    nature of the IO completion ports. We're still going to provide a minimal
    set of features for the sake of the rest of grpc. But grpc_pollset_work
    won't actually do any polling, and return as quickly as possible. */
 
-void grpc_pollset_init(grpc_pollset *pollset) {
+void grpc_pollset_init(grpc_pollset *pollset, gpr_mu **mu) {
+  *mu = &grpc_polling_mu;
   memset(pollset, 0, sizeof(*pollset));
   pollset->root_worker.links[GRPC_POLLSET_WORKER_LINK_POLLSET].next =
       pollset->root_worker.links[GRPC_POLLSET_WORKER_LINK_POLLSET].prev =
@@ -126,25 +128,25 @@
 }
 
 void grpc_pollset_work(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset,
-                       grpc_pollset_worker *worker, gpr_timespec now,
+                       grpc_pollset_worker **worker_hdl, gpr_timespec now,
                        gpr_timespec deadline) {
+  grpc_pollset_worker worker;
+  *worker_hdl = &worker;
+
   int added_worker = 0;
-  worker->links[GRPC_POLLSET_WORKER_LINK_POLLSET].next =
-      worker->links[GRPC_POLLSET_WORKER_LINK_POLLSET].prev =
-          worker->links[GRPC_POLLSET_WORKER_LINK_GLOBAL].next =
-              worker->links[GRPC_POLLSET_WORKER_LINK_GLOBAL].prev = NULL;
-  worker->kicked = 0;
-  worker->pollset = pollset;
-  gpr_cv_init(&worker->cv);
-  if (grpc_timer_check(exec_ctx, now, &deadline)) {
-    goto done;
-  }
+  worker.links[GRPC_POLLSET_WORKER_LINK_POLLSET].next =
+      worker.links[GRPC_POLLSET_WORKER_LINK_POLLSET].prev =
+          worker.links[GRPC_POLLSET_WORKER_LINK_GLOBAL].next =
+              worker.links[GRPC_POLLSET_WORKER_LINK_GLOBAL].prev = NULL;
+  worker.kicked = 0;
+  worker.pollset = pollset;
+  gpr_cv_init(&worker.cv);
   if (!pollset->kicked_without_pollers && !pollset->shutting_down) {
     if (g_active_poller == NULL) {
       grpc_pollset_worker *next_worker;
       /* become poller */
       pollset->is_iocp_worker = 1;
-      g_active_poller = worker;
+      g_active_poller = &worker;
       gpr_mu_unlock(&grpc_polling_mu);
       grpc_iocp_work(exec_ctx, deadline);
       grpc_exec_ctx_flush(exec_ctx);
@@ -171,12 +173,12 @@
       goto done;
     }
     push_front_worker(&g_global_root_worker, GRPC_POLLSET_WORKER_LINK_GLOBAL,
-                      worker);
+                      &worker);
     push_front_worker(&pollset->root_worker, GRPC_POLLSET_WORKER_LINK_POLLSET,
-                      worker);
+                      &worker);
     added_worker = 1;
-    while (!worker->kicked) {
-      if (gpr_cv_wait(&worker->cv, &grpc_polling_mu, deadline)) {
+    while (!worker.kicked) {
+      if (gpr_cv_wait(&worker.cv, &grpc_polling_mu, deadline)) {
         break;
       }
     }
@@ -190,10 +192,11 @@
     gpr_mu_lock(&grpc_polling_mu);
   }
   if (added_worker) {
-    remove_worker(worker, GRPC_POLLSET_WORKER_LINK_GLOBAL);
-    remove_worker(worker, GRPC_POLLSET_WORKER_LINK_POLLSET);
+    remove_worker(&worker, GRPC_POLLSET_WORKER_LINK_GLOBAL);
+    remove_worker(&worker, GRPC_POLLSET_WORKER_LINK_POLLSET);
   }
-  gpr_cv_destroy(&worker->cv);
+  gpr_cv_destroy(&worker.cv);
+  *worker_hdl = NULL;
 }
 
 void grpc_pollset_kick(grpc_pollset *p, grpc_pollset_worker *specific_worker) {
diff --git a/src/core/iomgr/pollset_windows.h b/src/core/iomgr/pollset_windows.h
index 65ba806..dc0b7a4 100644
--- a/src/core/iomgr/pollset_windows.h
+++ b/src/core/iomgr/pollset_windows.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -72,8 +72,4 @@
   grpc_closure *on_shutdown;
 };
 
-extern gpr_mu grpc_polling_mu;
-
-#define GRPC_POLLSET_MU(pollset) (&grpc_polling_mu)
-
 #endif /* GRPC_INTERNAL_CORE_IOMGR_POLLSET_WINDOWS_H */
diff --git a/src/core/iomgr/tcp_client_posix.c b/src/core/iomgr/tcp_client_posix.c
index c76c2e3..1572785 100644
--- a/src/core/iomgr/tcp_client_posix.c
+++ b/src/core/iomgr/tcp_client_posix.c
@@ -42,18 +42,20 @@
 #include <string.h>
 #include <unistd.h>
 
-#include "src/core/iomgr/timer.h"
-#include "src/core/iomgr/iomgr_posix.h"
-#include "src/core/iomgr/pollset_posix.h"
-#include "src/core/iomgr/sockaddr_utils.h"
-#include "src/core/iomgr/socket_utils_posix.h"
-#include "src/core/iomgr/tcp_posix.h"
-#include "src/core/support/string.h"
 #include <grpc/support/alloc.h>
 #include <grpc/support/log.h>
 #include <grpc/support/string_util.h>
 #include <grpc/support/time.h>
 
+#include "src/core/iomgr/iomgr_posix.h"
+#include "src/core/iomgr/pollset_posix.h"
+#include "src/core/iomgr/pollset_set_posix.h"
+#include "src/core/iomgr/sockaddr_utils.h"
+#include "src/core/iomgr/socket_utils_posix.h"
+#include "src/core/iomgr/tcp_posix.h"
+#include "src/core/iomgr/timer.h"
+#include "src/core/support/string.h"
+
 extern int grpc_tcp_trace;
 
 typedef struct {
diff --git a/src/core/iomgr/tcp_posix.c b/src/core/iomgr/tcp_posix.c
index 048e907..f74eb3f 100644
--- a/src/core/iomgr/tcp_posix.c
+++ b/src/core/iomgr/tcp_posix.c
@@ -40,8 +40,8 @@
 #include <errno.h>
 #include <stdlib.h>
 #include <string.h>
-#include <sys/types.h>
 #include <sys/socket.h>
+#include <sys/types.h>
 #include <unistd.h>
 
 #include <grpc/support/alloc.h>
@@ -51,9 +51,11 @@
 #include <grpc/support/sync.h>
 #include <grpc/support/time.h>
 
-#include "src/core/support/string.h"
 #include "src/core/debug/trace.h"
+#include "src/core/iomgr/pollset_posix.h"
+#include "src/core/iomgr/pollset_set_posix.h"
 #include "src/core/profiling/timers.h"
+#include "src/core/support/string.h"
 
 #ifdef GPR_HAVE_MSG_NOSIGNAL
 #define SENDMSG_FLAGS MSG_NOSIGNAL
diff --git a/src/core/iomgr/timer.c b/src/core/iomgr/timer.c
index a33d8f6..8379fff 100644
--- a/src/core/iomgr/timer.c
+++ b/src/core/iomgr/timer.c
@@ -34,7 +34,6 @@
 #include "src/core/iomgr/timer.h"
 
 #include "src/core/iomgr/timer_heap.h"
-#include "src/core/iomgr/timer_internal.h"
 #include "src/core/iomgr/time_averaged_stats.h"
 #include <grpc/support/log.h>
 #include <grpc/support/sync.h>
@@ -336,8 +335,8 @@
   return (int)n;
 }
 
-int grpc_timer_check(grpc_exec_ctx *exec_ctx, gpr_timespec now,
-                     gpr_timespec *next) {
+bool grpc_timer_check(grpc_exec_ctx *exec_ctx, gpr_timespec now,
+                      gpr_timespec *next) {
   GPR_ASSERT(now.clock_type == g_clock_type);
   return run_some_expired_timers(
       exec_ctx, now, next,
diff --git a/src/core/iomgr/timer.h b/src/core/iomgr/timer.h
index 720c9d5..9ad1e92 100644
--- a/src/core/iomgr/timer.h
+++ b/src/core/iomgr/timer.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -86,4 +86,24 @@
    Requires:  cancel() must happen after add() on a given timer */
 void grpc_timer_cancel(grpc_exec_ctx *exec_ctx, grpc_timer *timer);
 
+/* iomgr internal api for dealing with timers */
+
+/* Check for timers to be run, and run them.
+   Return true if timer callbacks were executed.
+   Drops drop_mu if it is non-null before executing callbacks.
+   If next is non-null, TRY to update *next with the next running timer
+   IF that timer occurs before *next current value.
+   *next is never guaranteed to be updated on any given execution; however,
+   with high probability at least one thread in the system will see an update
+   at any time slice. */
+
+bool grpc_timer_check(grpc_exec_ctx *exec_ctx, gpr_timespec now,
+                      gpr_timespec *next);
+void grpc_timer_list_init(gpr_timespec now);
+void grpc_timer_list_shutdown(grpc_exec_ctx *exec_ctx);
+
+/* the following must be implemented by each iomgr implementation */
+
+void grpc_kick_poller(void);
+
 #endif /* GRPC_INTERNAL_CORE_IOMGR_TIMER_H */
diff --git a/src/core/iomgr/timer_internal.h b/src/core/iomgr/timer_internal.h
deleted file mode 100644
index f182e73..0000000
--- a/src/core/iomgr/timer_internal.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- *
- * Copyright 2015, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#ifndef GRPC_INTERNAL_CORE_IOMGR_TIMER_INTERNAL_H
-#define GRPC_INTERNAL_CORE_IOMGR_TIMER_INTERNAL_H
-
-#include "src/core/iomgr/exec_ctx.h"
-#include <grpc/support/sync.h>
-#include <grpc/support/time.h>
-
-/* iomgr internal api for dealing with timers */
-
-/* Check for timers to be run, and run them.
-   Return non zero if timer callbacks were executed.
-   Drops drop_mu if it is non-null before executing callbacks.
-   If next is non-null, TRY to update *next with the next running timer
-   IF that timer occurs before *next current value.
-   *next is never guaranteed to be updated on any given execution; however,
-   with high probability at least one thread in the system will see an update
-   at any time slice. */
-
-int grpc_timer_check(grpc_exec_ctx* exec_ctx, gpr_timespec now,
-                     gpr_timespec* next);
-void grpc_timer_list_init(gpr_timespec now);
-void grpc_timer_list_shutdown(grpc_exec_ctx* exec_ctx);
-
-/* the following must be implemented by each iomgr implementation */
-
-void grpc_kick_poller(void);
-
-#endif /* GRPC_INTERNAL_CORE_IOMGR_TIMER_INTERNAL_H */
diff --git a/src/core/iomgr/udp_server.h b/src/core/iomgr/udp_server.h
index 73a21c8..a9d0489 100644
--- a/src/core/iomgr/udp_server.h
+++ b/src/core/iomgr/udp_server.h
@@ -35,6 +35,7 @@
 #define GRPC_INTERNAL_CORE_IOMGR_UDP_SERVER_H
 
 #include "src/core/iomgr/endpoint.h"
+#include "src/core/iomgr/fd_posix.h"
 
 /* Forward decl of grpc_server */
 typedef struct grpc_server grpc_server;
diff --git a/src/core/iomgr/workqueue_posix.c b/src/core/iomgr/workqueue_posix.c
index da11df6..c096dbf 100644
--- a/src/core/iomgr/workqueue_posix.c
+++ b/src/core/iomgr/workqueue_posix.c
@@ -44,6 +44,7 @@
 #include <grpc/support/useful.h>
 
 #include "src/core/iomgr/fd_posix.h"
+#include "src/core/iomgr/pollset_posix.h"
 
 static void on_readable(grpc_exec_ctx *exec_ctx, void *arg, bool success);
 
diff --git a/src/core/iomgr/workqueue_posix.h b/src/core/iomgr/workqueue_posix.h
index 589034f..68f195e 100644
--- a/src/core/iomgr/workqueue_posix.h
+++ b/src/core/iomgr/workqueue_posix.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -34,6 +34,8 @@
 #ifndef GRPC_INTERNAL_CORE_IOMGR_WORKQUEUE_POSIX_H
 #define GRPC_INTERNAL_CORE_IOMGR_WORKQUEUE_POSIX_H
 
+#include "src/core/iomgr/wakeup_fd_posix.h"
+
 struct grpc_fd;
 
 struct grpc_workqueue {
diff --git a/src/core/proto/grpc/lb/v0/load_balancer.pb.c b/src/core/proto/grpc/lb/v0/load_balancer.pb.c
new file mode 100644
index 0000000..59aae30
--- /dev/null
+++ b/src/core/proto/grpc/lb/v0/load_balancer.pb.c
@@ -0,0 +1,119 @@
+/*
+ *
+ * Copyright 2016, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+/* Automatically generated nanopb constant definitions */
+/* Generated by nanopb-0.3.5-dev */
+
+#include "src/core/proto/grpc/lb/v0/load_balancer.pb.h"
+
+#if PB_PROTO_HEADER_VERSION != 30
+#error Regenerate this file with the current version of nanopb generator.
+#endif
+
+
+
+const pb_field_t grpc_lb_v0_Duration_fields[3] = {
+    PB_FIELD(  1, INT64   , OPTIONAL, STATIC  , FIRST, grpc_lb_v0_Duration, seconds, seconds, 0),
+    PB_FIELD(  2, INT32   , OPTIONAL, STATIC  , OTHER, grpc_lb_v0_Duration, nanos, seconds, 0),
+    PB_LAST_FIELD
+};
+
+const pb_field_t grpc_lb_v0_LoadBalanceRequest_fields[3] = {
+    PB_FIELD(  1, MESSAGE , OPTIONAL, STATIC  , FIRST, grpc_lb_v0_LoadBalanceRequest, initial_request, initial_request, &grpc_lb_v0_InitialLoadBalanceRequest_fields),
+    PB_FIELD(  2, MESSAGE , OPTIONAL, STATIC  , OTHER, grpc_lb_v0_LoadBalanceRequest, client_stats, initial_request, &grpc_lb_v0_ClientStats_fields),
+    PB_LAST_FIELD
+};
+
+const pb_field_t grpc_lb_v0_InitialLoadBalanceRequest_fields[2] = {
+    PB_FIELD(  1, STRING  , OPTIONAL, STATIC  , FIRST, grpc_lb_v0_InitialLoadBalanceRequest, name, name, 0),
+    PB_LAST_FIELD
+};
+
+const pb_field_t grpc_lb_v0_ClientStats_fields[4] = {
+    PB_FIELD(  1, INT64   , OPTIONAL, STATIC  , FIRST, grpc_lb_v0_ClientStats, total_requests, total_requests, 0),
+    PB_FIELD(  2, INT64   , OPTIONAL, STATIC  , OTHER, grpc_lb_v0_ClientStats, client_rpc_errors, total_requests, 0),
+    PB_FIELD(  3, INT64   , OPTIONAL, STATIC  , OTHER, grpc_lb_v0_ClientStats, dropped_requests, client_rpc_errors, 0),
+    PB_LAST_FIELD
+};
+
+const pb_field_t grpc_lb_v0_LoadBalanceResponse_fields[3] = {
+    PB_FIELD(  1, MESSAGE , OPTIONAL, STATIC  , FIRST, grpc_lb_v0_LoadBalanceResponse, initial_response, initial_response, &grpc_lb_v0_InitialLoadBalanceResponse_fields),
+    PB_FIELD(  2, MESSAGE , OPTIONAL, STATIC  , OTHER, grpc_lb_v0_LoadBalanceResponse, server_list, initial_response, &grpc_lb_v0_ServerList_fields),
+    PB_LAST_FIELD
+};
+
+const pb_field_t grpc_lb_v0_InitialLoadBalanceResponse_fields[4] = {
+    PB_FIELD(  1, STRING  , OPTIONAL, STATIC  , FIRST, grpc_lb_v0_InitialLoadBalanceResponse, client_config, client_config, 0),
+    PB_FIELD(  2, STRING  , OPTIONAL, STATIC  , OTHER, grpc_lb_v0_InitialLoadBalanceResponse, load_balancer_delegate, client_config, 0),
+    PB_FIELD(  3, MESSAGE , OPTIONAL, STATIC  , OTHER, grpc_lb_v0_InitialLoadBalanceResponse, client_stats_report_interval, load_balancer_delegate, &grpc_lb_v0_Duration_fields),
+    PB_LAST_FIELD
+};
+
+const pb_field_t grpc_lb_v0_ServerList_fields[3] = {
+    PB_FIELD(  1, MESSAGE , REPEATED, CALLBACK, FIRST, grpc_lb_v0_ServerList, servers, servers, &grpc_lb_v0_Server_fields),
+    PB_FIELD(  3, MESSAGE , OPTIONAL, STATIC  , OTHER, grpc_lb_v0_ServerList, expiration_interval, servers, &grpc_lb_v0_Duration_fields),
+    PB_LAST_FIELD
+};
+
+const pb_field_t grpc_lb_v0_Server_fields[5] = {
+    PB_FIELD(  1, STRING  , OPTIONAL, STATIC  , FIRST, grpc_lb_v0_Server, ip_address, ip_address, 0),
+    PB_FIELD(  2, INT32   , OPTIONAL, STATIC  , OTHER, grpc_lb_v0_Server, port, ip_address, 0),
+    PB_FIELD(  3, BYTES   , OPTIONAL, STATIC  , OTHER, grpc_lb_v0_Server, load_balance_token, port, 0),
+    PB_FIELD(  4, BOOL    , OPTIONAL, STATIC  , OTHER, grpc_lb_v0_Server, drop_request, load_balance_token, 0),
+    PB_LAST_FIELD
+};
+
+
+/* Check that field information fits in pb_field_t */
+#if !defined(PB_FIELD_32BIT)
+/* If you get an error here, it means that you need to define PB_FIELD_32BIT
+ * compile-time option. You can do that in pb.h or on compiler command line.
+ * 
+ * The reason you need to do this is that some of your messages contain tag
+ * numbers or field sizes that are larger than what can fit in 8 or 16 bit
+ * field descriptors.
+ */
+PB_STATIC_ASSERT((pb_membersize(grpc_lb_v0_LoadBalanceRequest, initial_request) < 65536 && pb_membersize(grpc_lb_v0_LoadBalanceRequest, client_stats) < 65536 && pb_membersize(grpc_lb_v0_LoadBalanceResponse, initial_response) < 65536 && pb_membersize(grpc_lb_v0_LoadBalanceResponse, server_list) < 65536 && pb_membersize(grpc_lb_v0_InitialLoadBalanceResponse, client_stats_report_interval) < 65536 && pb_membersize(grpc_lb_v0_ServerList, servers) < 65536 && pb_membersize(grpc_lb_v0_ServerList, expiration_interval) < 65536), YOU_MUST_DEFINE_PB_FIELD_32BIT_FOR_MESSAGES_grpc_lb_v0_Duration_grpc_lb_v0_LoadBalanceRequest_grpc_lb_v0_InitialLoadBalanceRequest_grpc_lb_v0_ClientStats_grpc_lb_v0_LoadBalanceResponse_grpc_lb_v0_InitialLoadBalanceResponse_grpc_lb_v0_ServerList_grpc_lb_v0_Server)
+#endif
+
+#if !defined(PB_FIELD_16BIT) && !defined(PB_FIELD_32BIT)
+/* If you get an error here, it means that you need to define PB_FIELD_16BIT
+ * compile-time option. You can do that in pb.h or on compiler command line.
+ * 
+ * The reason you need to do this is that some of your messages contain tag
+ * numbers or field sizes that are larger than what can fit in the default
+ * 8 bit descriptors.
+ */
+PB_STATIC_ASSERT((pb_membersize(grpc_lb_v0_LoadBalanceRequest, initial_request) < 256 && pb_membersize(grpc_lb_v0_LoadBalanceRequest, client_stats) < 256 && pb_membersize(grpc_lb_v0_LoadBalanceResponse, initial_response) < 256 && pb_membersize(grpc_lb_v0_LoadBalanceResponse, server_list) < 256 && pb_membersize(grpc_lb_v0_InitialLoadBalanceResponse, client_stats_report_interval) < 256 && pb_membersize(grpc_lb_v0_ServerList, servers) < 256 && pb_membersize(grpc_lb_v0_ServerList, expiration_interval) < 256), YOU_MUST_DEFINE_PB_FIELD_16BIT_FOR_MESSAGES_grpc_lb_v0_Duration_grpc_lb_v0_LoadBalanceRequest_grpc_lb_v0_InitialLoadBalanceRequest_grpc_lb_v0_ClientStats_grpc_lb_v0_LoadBalanceResponse_grpc_lb_v0_InitialLoadBalanceResponse_grpc_lb_v0_ServerList_grpc_lb_v0_Server)
+#endif
+
+
diff --git a/src/core/proto/grpc/lb/v0/load_balancer.pb.h b/src/core/proto/grpc/lb/v0/load_balancer.pb.h
new file mode 100644
index 0000000..3599f88
--- /dev/null
+++ b/src/core/proto/grpc/lb/v0/load_balancer.pb.h
@@ -0,0 +1,182 @@
+/*
+ *
+ * Copyright 2016, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+/* Automatically generated nanopb header */
+/* Generated by nanopb-0.3.5-dev */
+
+#ifndef PB_LOAD_BALANCER_PB_H_INCLUDED
+#define PB_LOAD_BALANCER_PB_H_INCLUDED
+#include "third_party/nanopb/pb.h"
+#if PB_PROTO_HEADER_VERSION != 30
+#error Regenerate this file with the current version of nanopb generator.
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Struct definitions */
+typedef struct _grpc_lb_v0_ClientStats {
+    bool has_total_requests;
+    int64_t total_requests;
+    bool has_client_rpc_errors;
+    int64_t client_rpc_errors;
+    bool has_dropped_requests;
+    int64_t dropped_requests;
+} grpc_lb_v0_ClientStats;
+
+typedef struct _grpc_lb_v0_Duration {
+    bool has_seconds;
+    int64_t seconds;
+    bool has_nanos;
+    int32_t nanos;
+} grpc_lb_v0_Duration;
+
+typedef struct _grpc_lb_v0_InitialLoadBalanceRequest {
+    bool has_name;
+    char name[128];
+} grpc_lb_v0_InitialLoadBalanceRequest;
+
+typedef PB_BYTES_ARRAY_T(64) grpc_lb_v0_Server_load_balance_token_t;
+typedef struct _grpc_lb_v0_Server {
+    bool has_ip_address;
+    char ip_address[46];
+    bool has_port;
+    int32_t port;
+    bool has_load_balance_token;
+    grpc_lb_v0_Server_load_balance_token_t load_balance_token;
+    bool has_drop_request;
+    bool drop_request;
+} grpc_lb_v0_Server;
+
+typedef struct _grpc_lb_v0_InitialLoadBalanceResponse {
+    bool has_client_config;
+    char client_config[64];
+    bool has_load_balancer_delegate;
+    char load_balancer_delegate[64];
+    bool has_client_stats_report_interval;
+    grpc_lb_v0_Duration client_stats_report_interval;
+} grpc_lb_v0_InitialLoadBalanceResponse;
+
+typedef struct _grpc_lb_v0_LoadBalanceRequest {
+    bool has_initial_request;
+    grpc_lb_v0_InitialLoadBalanceRequest initial_request;
+    bool has_client_stats;
+    grpc_lb_v0_ClientStats client_stats;
+} grpc_lb_v0_LoadBalanceRequest;
+
+typedef struct _grpc_lb_v0_ServerList {
+    pb_callback_t servers;
+    bool has_expiration_interval;
+    grpc_lb_v0_Duration expiration_interval;
+} grpc_lb_v0_ServerList;
+
+typedef struct _grpc_lb_v0_LoadBalanceResponse {
+    bool has_initial_response;
+    grpc_lb_v0_InitialLoadBalanceResponse initial_response;
+    bool has_server_list;
+    grpc_lb_v0_ServerList server_list;
+} grpc_lb_v0_LoadBalanceResponse;
+
+/* Default values for struct fields */
+
+/* Initializer values for message structs */
+#define grpc_lb_v0_Duration_init_default         {false, 0, false, 0}
+#define grpc_lb_v0_LoadBalanceRequest_init_default {false, grpc_lb_v0_InitialLoadBalanceRequest_init_default, false, grpc_lb_v0_ClientStats_init_default}
+#define grpc_lb_v0_InitialLoadBalanceRequest_init_default {false, ""}
+#define grpc_lb_v0_ClientStats_init_default      {false, 0, false, 0, false, 0}
+#define grpc_lb_v0_LoadBalanceResponse_init_default {false, grpc_lb_v0_InitialLoadBalanceResponse_init_default, false, grpc_lb_v0_ServerList_init_default}
+#define grpc_lb_v0_InitialLoadBalanceResponse_init_default {false, "", false, "", false, grpc_lb_v0_Duration_init_default}
+#define grpc_lb_v0_ServerList_init_default       {{{NULL}, NULL}, false, grpc_lb_v0_Duration_init_default}
+#define grpc_lb_v0_Server_init_default           {false, "", false, 0, false, {0, {0}}, false, 0}
+#define grpc_lb_v0_Duration_init_zero            {false, 0, false, 0}
+#define grpc_lb_v0_LoadBalanceRequest_init_zero  {false, grpc_lb_v0_InitialLoadBalanceRequest_init_zero, false, grpc_lb_v0_ClientStats_init_zero}
+#define grpc_lb_v0_InitialLoadBalanceRequest_init_zero {false, ""}
+#define grpc_lb_v0_ClientStats_init_zero         {false, 0, false, 0, false, 0}
+#define grpc_lb_v0_LoadBalanceResponse_init_zero {false, grpc_lb_v0_InitialLoadBalanceResponse_init_zero, false, grpc_lb_v0_ServerList_init_zero}
+#define grpc_lb_v0_InitialLoadBalanceResponse_init_zero {false, "", false, "", false, grpc_lb_v0_Duration_init_zero}
+#define grpc_lb_v0_ServerList_init_zero          {{{NULL}, NULL}, false, grpc_lb_v0_Duration_init_zero}
+#define grpc_lb_v0_Server_init_zero              {false, "", false, 0, false, {0, {0}}, false, 0}
+
+/* Field tags (for use in manual encoding/decoding) */
+#define grpc_lb_v0_ClientStats_total_requests_tag 1
+#define grpc_lb_v0_ClientStats_client_rpc_errors_tag 2
+#define grpc_lb_v0_ClientStats_dropped_requests_tag 3
+#define grpc_lb_v0_Duration_seconds_tag          1
+#define grpc_lb_v0_Duration_nanos_tag            2
+#define grpc_lb_v0_InitialLoadBalanceRequest_name_tag 1
+#define grpc_lb_v0_Server_ip_address_tag         1
+#define grpc_lb_v0_Server_port_tag               2
+#define grpc_lb_v0_Server_load_balance_token_tag 3
+#define grpc_lb_v0_Server_drop_request_tag       4
+#define grpc_lb_v0_InitialLoadBalanceResponse_client_config_tag 1
+#define grpc_lb_v0_InitialLoadBalanceResponse_load_balancer_delegate_tag 2
+#define grpc_lb_v0_InitialLoadBalanceResponse_client_stats_report_interval_tag 3
+#define grpc_lb_v0_LoadBalanceRequest_initial_request_tag 1
+#define grpc_lb_v0_LoadBalanceRequest_client_stats_tag 2
+#define grpc_lb_v0_ServerList_servers_tag        1
+#define grpc_lb_v0_ServerList_expiration_interval_tag 3
+#define grpc_lb_v0_LoadBalanceResponse_initial_response_tag 1
+#define grpc_lb_v0_LoadBalanceResponse_server_list_tag 2
+
+/* Struct field encoding specification for nanopb */
+extern const pb_field_t grpc_lb_v0_Duration_fields[3];
+extern const pb_field_t grpc_lb_v0_LoadBalanceRequest_fields[3];
+extern const pb_field_t grpc_lb_v0_InitialLoadBalanceRequest_fields[2];
+extern const pb_field_t grpc_lb_v0_ClientStats_fields[4];
+extern const pb_field_t grpc_lb_v0_LoadBalanceResponse_fields[3];
+extern const pb_field_t grpc_lb_v0_InitialLoadBalanceResponse_fields[4];
+extern const pb_field_t grpc_lb_v0_ServerList_fields[3];
+extern const pb_field_t grpc_lb_v0_Server_fields[5];
+
+/* Maximum encoded size of messages (where known) */
+#define grpc_lb_v0_Duration_size                 22
+#define grpc_lb_v0_LoadBalanceRequest_size       169
+#define grpc_lb_v0_InitialLoadBalanceRequest_size 131
+#define grpc_lb_v0_ClientStats_size              33
+#define grpc_lb_v0_LoadBalanceResponse_size      (165 + grpc_lb_v0_ServerList_size)
+#define grpc_lb_v0_InitialLoadBalanceResponse_size 156
+#define grpc_lb_v0_Server_size                   127
+
+/* Message IDs (where set with "msgid" option) */
+#ifdef PB_MSGID
+
+#define LOAD_BALANCER_MESSAGES \
+
+
+#endif
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif
diff --git a/src/core/security/base64.c b/src/core/security/b64.c
similarity index 99%
rename from src/core/security/base64.c
rename to src/core/security/b64.c
index 8367c16..c40b528 100644
--- a/src/core/security/base64.c
+++ b/src/core/security/b64.c
@@ -31,7 +31,7 @@
  *
  */
 
-#include "src/core/security/base64.h"
+#include "src/core/security/b64.h"
 
 #include <stdint.h>
 #include <string.h>
diff --git a/src/core/security/base64.h b/src/core/security/b64.h
similarity index 98%
rename from src/core/security/base64.h
rename to src/core/security/b64.h
index 31ae982..3e3b521 100644
--- a/src/core/security/base64.h
+++ b/src/core/security/b64.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/src/core/security/client_auth_filter.c b/src/core/security/client_auth_filter.c
index 57b367d..332d425 100644
--- a/src/core/security/client_auth_filter.c
+++ b/src/core/security/client_auth_filter.c
@@ -310,7 +310,6 @@
   GPR_ASSERT(auth_context != NULL);
 
   /* initialize members */
-  GPR_ASSERT(sc->is_client_side);
   chand->security_connector =
       (grpc_channel_security_connector *)GRPC_SECURITY_CONNECTOR_REF(
           sc, "client_auth_filter");
diff --git a/src/core/security/credentials.c b/src/core/security/credentials.c
index c58574b..b4fa616 100644
--- a/src/core/security/credentials.c
+++ b/src/core/security/credentials.c
@@ -166,7 +166,7 @@
 }
 
 grpc_security_status grpc_server_credentials_create_security_connector(
-    grpc_server_credentials *creds, grpc_security_connector **sc) {
+    grpc_server_credentials *creds, grpc_server_security_connector **sc) {
   if (creds == NULL || creds->vtable->create_security_connector == NULL) {
     gpr_log(GPR_ERROR, "Server credentials cannot create security context.");
     return GRPC_SECURITY_ERROR;
@@ -298,7 +298,7 @@
 }
 
 static grpc_security_status ssl_server_create_security_connector(
-    grpc_server_credentials *creds, grpc_security_connector **sc) {
+    grpc_server_credentials *creds, grpc_server_security_connector **sc) {
   grpc_ssl_server_credentials *c = (grpc_ssl_server_credentials *)creds;
   return grpc_ssl_server_security_connector_create(&c->config, sc);
 }
@@ -894,7 +894,7 @@
 
 static grpc_security_status
 fake_transport_security_server_create_security_connector(
-    grpc_server_credentials *c, grpc_security_connector **sc) {
+    grpc_server_credentials *c, grpc_server_security_connector **sc) {
   *sc = grpc_fake_server_security_connector_create();
   return GRPC_SECURITY_OK;
 }
diff --git a/src/core/security/credentials.h b/src/core/security/credentials.h
index 3cd652c..0de4cd9 100644
--- a/src/core/security/credentials.h
+++ b/src/core/security/credentials.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -234,7 +234,7 @@
 typedef struct {
   void (*destruct)(grpc_server_credentials *c);
   grpc_security_status (*create_security_connector)(
-      grpc_server_credentials *c, grpc_security_connector **sc);
+      grpc_server_credentials *c, grpc_server_security_connector **sc);
 } grpc_server_credentials_vtable;
 
 struct grpc_server_credentials {
@@ -245,7 +245,7 @@
 };
 
 grpc_security_status grpc_server_credentials_create_security_connector(
-    grpc_server_credentials *creds, grpc_security_connector **sc);
+    grpc_server_credentials *creds, grpc_server_security_connector **sc);
 
 grpc_server_credentials *grpc_server_credentials_ref(
     grpc_server_credentials *creds);
diff --git a/src/core/security/google_default_credentials.c b/src/core/security/google_default_credentials.c
index f3ac145..1f4f3e4 100644
--- a/src/core/security/google_default_credentials.c
+++ b/src/core/security/google_default_credentials.c
@@ -41,7 +41,7 @@
 
 #include "src/core/httpcli/httpcli.h"
 #include "src/core/support/env.h"
-#include "src/core/support/file.h"
+#include "src/core/support/load_file.h"
 #include "src/core/surface/api_trace.h"
 
 /* -- Constants. -- */
@@ -52,13 +52,14 @@
 
 static grpc_channel_credentials *default_credentials = NULL;
 static int compute_engine_detection_done = 0;
-static gpr_mu g_mu;
+static gpr_mu g_state_mu;
+static gpr_mu *g_polling_mu;
 static gpr_once g_once = GPR_ONCE_INIT;
 
-static void init_default_credentials(void) { gpr_mu_init(&g_mu); }
+static void init_default_credentials(void) { gpr_mu_init(&g_state_mu); }
 
 typedef struct {
-  grpc_pollset pollset;
+  grpc_pollset *pollset;
   int is_done;
   int success;
 } compute_engine_detector;
@@ -80,10 +81,10 @@
       }
     }
   }
-  gpr_mu_lock(GRPC_POLLSET_MU(&detector->pollset));
+  gpr_mu_lock(g_polling_mu);
   detector->is_done = 1;
-  grpc_pollset_kick(&detector->pollset, NULL);
-  gpr_mu_unlock(GRPC_POLLSET_MU(&detector->pollset));
+  grpc_pollset_kick(detector->pollset, NULL);
+  gpr_mu_unlock(g_polling_mu);
 }
 
 static void destroy_pollset(grpc_exec_ctx *exec_ctx, void *p, bool s) {
@@ -101,7 +102,8 @@
      on compute engine. */
   gpr_timespec max_detection_delay = gpr_time_from_seconds(1, GPR_TIMESPAN);
 
-  grpc_pollset_init(&detector.pollset);
+  detector.pollset = gpr_malloc(grpc_pollset_size());
+  grpc_pollset_init(detector.pollset, &g_polling_mu);
   detector.is_done = 0;
   detector.success = 0;
 
@@ -112,7 +114,7 @@
   grpc_httpcli_context_init(&context);
 
   grpc_httpcli_get(
-      &exec_ctx, &context, &detector.pollset, &request,
+      &exec_ctx, &context, detector.pollset, &request,
       gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), max_detection_delay),
       on_compute_engine_detection_http_response, &detector);
 
@@ -120,19 +122,22 @@
 
   /* Block until we get the response. This is not ideal but this should only be
      called once for the lifetime of the process by the default credentials. */
-  gpr_mu_lock(GRPC_POLLSET_MU(&detector.pollset));
+  gpr_mu_lock(g_polling_mu);
   while (!detector.is_done) {
-    grpc_pollset_worker worker;
-    grpc_pollset_work(&exec_ctx, &detector.pollset, &worker,
+    grpc_pollset_worker *worker = NULL;
+    grpc_pollset_work(&exec_ctx, detector.pollset, &worker,
                       gpr_now(GPR_CLOCK_MONOTONIC),
                       gpr_inf_future(GPR_CLOCK_MONOTONIC));
   }
-  gpr_mu_unlock(GRPC_POLLSET_MU(&detector.pollset));
+  gpr_mu_unlock(g_polling_mu);
 
   grpc_httpcli_context_destroy(&context);
-  grpc_closure_init(&destroy_closure, destroy_pollset, &detector.pollset);
-  grpc_pollset_shutdown(&exec_ctx, &detector.pollset, &destroy_closure);
+  grpc_closure_init(&destroy_closure, destroy_pollset, detector.pollset);
+  grpc_pollset_shutdown(&exec_ctx, detector.pollset, &destroy_closure);
   grpc_exec_ctx_finish(&exec_ctx);
+  g_polling_mu = NULL;
+
+  gpr_free(detector.pollset);
 
   return detector.success;
 }
@@ -184,7 +189,7 @@
 
   gpr_once_init(&g_once, init_default_credentials);
 
-  gpr_mu_lock(&g_mu);
+  gpr_mu_lock(&g_state_mu);
 
   if (default_credentials != NULL) {
     result = grpc_channel_credentials_ref(default_credentials);
@@ -230,19 +235,19 @@
       gpr_log(GPR_ERROR, "Could not create google default credentials.");
     }
   }
-  gpr_mu_unlock(&g_mu);
+  gpr_mu_unlock(&g_state_mu);
   return result;
 }
 
 void grpc_flush_cached_google_default_credentials(void) {
   gpr_once_init(&g_once, init_default_credentials);
-  gpr_mu_lock(&g_mu);
+  gpr_mu_lock(&g_state_mu);
   if (default_credentials != NULL) {
     grpc_channel_credentials_unref(default_credentials);
     default_credentials = NULL;
   }
   compute_engine_detection_done = 0;
-  gpr_mu_unlock(&g_mu);
+  gpr_mu_unlock(&g_state_mu);
 }
 
 /* -- Well known credentials path. -- */
diff --git a/src/core/security/handshake.c b/src/core/security/handshake.c
index a8b2fef..b5bb666 100644
--- a/src/core/security/handshake.c
+++ b/src/core/security/handshake.c
@@ -33,6 +33,7 @@
 
 #include "src/core/security/handshake.h"
 
+#include <stdbool.h>
 #include <string.h>
 
 #include "src/core/security/security_context.h"
@@ -46,6 +47,7 @@
 typedef struct {
   grpc_security_connector *connector;
   tsi_handshaker *handshaker;
+  bool is_client_side;
   unsigned char *handshake_buffer;
   size_t handshake_buffer_size;
   grpc_endpoint *wrapped_endpoint;
@@ -67,9 +69,11 @@
                                            bool success);
 
 static void security_connector_remove_handshake(grpc_security_handshake *h) {
+  GPR_ASSERT(!h->is_client_side);
   grpc_security_connector_handshake_list *node;
   grpc_security_connector_handshake_list *tmp;
-  grpc_security_connector *sc = h->connector;
+  grpc_server_security_connector *sc =
+      (grpc_server_security_connector *)h->connector;
   gpr_mu_lock(&sc->mu);
   node = sc->handshaking_handshakes;
   if (node && node->handshake == h) {
@@ -94,7 +98,7 @@
 static void security_handshake_done(grpc_exec_ctx *exec_ctx,
                                     grpc_security_handshake *h,
                                     int is_success) {
-  if (!h->connector->is_client_side) {
+  if (!h->is_client_side) {
     security_connector_remove_handshake(h);
   }
   if (is_success) {
@@ -290,6 +294,7 @@
 void grpc_do_security_handshake(grpc_exec_ctx *exec_ctx,
                                 tsi_handshaker *handshaker,
                                 grpc_security_connector *connector,
+                                bool is_client_side,
                                 grpc_endpoint *nonsecure_endpoint,
                                 grpc_security_handshake_done_cb cb,
                                 void *user_data) {
@@ -298,6 +303,7 @@
   memset(h, 0, sizeof(grpc_security_handshake));
   h->handshaker = handshaker;
   h->connector = GRPC_SECURITY_CONNECTOR_REF(connector, "handshake");
+  h->is_client_side = is_client_side;
   h->handshake_buffer_size = GRPC_INITIAL_HANDSHAKE_BUFFER_SIZE;
   h->handshake_buffer = gpr_malloc(h->handshake_buffer_size);
   h->wrapped_endpoint = nonsecure_endpoint;
@@ -310,13 +316,15 @@
   gpr_slice_buffer_init(&h->left_overs);
   gpr_slice_buffer_init(&h->outgoing);
   gpr_slice_buffer_init(&h->incoming);
-  if (!connector->is_client_side) {
+  if (!is_client_side) {
+    grpc_server_security_connector *server_connector =
+        (grpc_server_security_connector *)connector;
     handshake_node = gpr_malloc(sizeof(grpc_security_connector_handshake_list));
     handshake_node->handshake = h;
-    gpr_mu_lock(&connector->mu);
-    handshake_node->next = connector->handshaking_handshakes;
-    connector->handshaking_handshakes = handshake_node;
-    gpr_mu_unlock(&connector->mu);
+    gpr_mu_lock(&server_connector->mu);
+    handshake_node->next = server_connector->handshaking_handshakes;
+    server_connector->handshaking_handshakes = handshake_node;
+    gpr_mu_unlock(&server_connector->mu);
   }
   send_handshake_bytes_to_peer(exec_ctx, h);
 }
diff --git a/src/core/security/handshake.h b/src/core/security/handshake.h
index 44215d1..db8b374 100644
--- a/src/core/security/handshake.h
+++ b/src/core/security/handshake.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -41,6 +41,7 @@
 void grpc_do_security_handshake(grpc_exec_ctx *exec_ctx,
                                 tsi_handshaker *handshaker,
                                 grpc_security_connector *connector,
+                                bool is_client_side,
                                 grpc_endpoint *nonsecure_endpoint,
                                 grpc_security_handshake_done_cb cb,
                                 void *user_data);
diff --git a/src/core/security/json_token.c b/src/core/security/json_token.c
index 762f029..372e5bf 100644
--- a/src/core/security/json_token.c
+++ b/src/core/security/json_token.c
@@ -39,7 +39,7 @@
 #include <grpc/support/log.h>
 #include <grpc/support/string_util.h>
 
-#include "src/core/security/base64.h"
+#include "src/core/security/b64.h"
 #include "src/core/support/string.h"
 
 #include <openssl/bio.h>
diff --git a/src/core/security/jwt_verifier.c b/src/core/security/jwt_verifier.c
index 042a117..928c6c1 100644
--- a/src/core/security/jwt_verifier.c
+++ b/src/core/security/jwt_verifier.c
@@ -37,7 +37,7 @@
 #include <string.h>
 
 #include "src/core/httpcli/httpcli.h"
-#include "src/core/security/base64.h"
+#include "src/core/security/b64.h"
 #include "src/core/tsi/ssl_types.h"
 
 #include <grpc/support/alloc.h>
diff --git a/src/core/security/security_connector.c b/src/core/security/security_connector.c
index b462053..33c62a2 100644
--- a/src/core/security/security_connector.c
+++ b/src/core/security/security_connector.c
@@ -33,22 +33,23 @@
 
 #include "src/core/security/security_connector.h"
 
+#include <stdbool.h>
 #include <string.h>
 
-#include "src/core/security/credentials.h"
-#include "src/core/security/handshake.h"
-#include "src/core/security/secure_endpoint.h"
-#include "src/core/security/security_context.h"
-#include "src/core/support/env.h"
-#include "src/core/support/file.h"
-#include "src/core/support/string.h"
-#include "src/core/transport/chttp2/alpn.h"
-
 #include <grpc/support/alloc.h>
 #include <grpc/support/host_port.h>
 #include <grpc/support/log.h>
 #include <grpc/support/slice_buffer.h>
 #include <grpc/support/string_util.h>
+
+#include "src/core/security/credentials.h"
+#include "src/core/security/handshake.h"
+#include "src/core/security/secure_endpoint.h"
+#include "src/core/security/security_context.h"
+#include "src/core/support/env.h"
+#include "src/core/support/load_file.h"
+#include "src/core/support/string.h"
+#include "src/core/transport/chttp2/alpn.h"
 #include "src/core/tsi/fake_transport_security.h"
 #include "src/core/tsi/ssl_transport_security.h"
 
@@ -110,31 +111,39 @@
   return NULL;
 }
 
-void grpc_security_connector_shutdown(grpc_exec_ctx *exec_ctx,
-                                      grpc_security_connector *connector) {
+void grpc_server_security_connector_shutdown(
+    grpc_exec_ctx *exec_ctx, grpc_server_security_connector *connector) {
   grpc_security_connector_handshake_list *tmp;
-  if (!connector->is_client_side) {
-    gpr_mu_lock(&connector->mu);
-    while (connector->handshaking_handshakes) {
-      tmp = connector->handshaking_handshakes;
-      grpc_security_handshake_shutdown(
-          exec_ctx, connector->handshaking_handshakes->handshake);
-      connector->handshaking_handshakes = tmp->next;
-      gpr_free(tmp);
-    }
-    gpr_mu_unlock(&connector->mu);
+  gpr_mu_lock(&connector->mu);
+  while (connector->handshaking_handshakes) {
+    tmp = connector->handshaking_handshakes;
+    grpc_security_handshake_shutdown(
+        exec_ctx, connector->handshaking_handshakes->handshake);
+    connector->handshaking_handshakes = tmp->next;
+    gpr_free(tmp);
   }
+  gpr_mu_unlock(&connector->mu);
 }
 
-void grpc_security_connector_do_handshake(grpc_exec_ctx *exec_ctx,
-                                          grpc_security_connector *sc,
-                                          grpc_endpoint *nonsecure_endpoint,
-                                          grpc_security_handshake_done_cb cb,
-                                          void *user_data) {
+void grpc_channel_security_connector_do_handshake(
+    grpc_exec_ctx *exec_ctx, grpc_channel_security_connector *sc,
+    grpc_endpoint *nonsecure_endpoint, grpc_security_handshake_done_cb cb,
+    void *user_data) {
   if (sc == NULL || nonsecure_endpoint == NULL) {
     cb(exec_ctx, user_data, GRPC_SECURITY_ERROR, NULL, NULL);
   } else {
-    sc->vtable->do_handshake(exec_ctx, sc, nonsecure_endpoint, cb, user_data);
+    sc->do_handshake(exec_ctx, sc, nonsecure_endpoint, cb, user_data);
+  }
+}
+
+void grpc_server_security_connector_do_handshake(
+    grpc_exec_ctx *exec_ctx, grpc_server_security_connector *sc,
+    grpc_tcp_server_acceptor *acceptor, grpc_endpoint *nonsecure_endpoint,
+    grpc_security_handshake_done_cb cb, void *user_data) {
+  if (sc == NULL || nonsecure_endpoint == NULL) {
+    cb(exec_ctx, user_data, GRPC_SECURITY_ERROR, NULL, NULL);
+  } else {
+    sc->do_handshake(exec_ctx, sc, acceptor, nonsecure_endpoint, cb, user_data);
   }
 }
 
@@ -248,7 +257,8 @@
 }
 
 static void fake_server_destroy(grpc_security_connector *sc) {
-  gpr_mu_destroy(&sc->mu);
+  grpc_server_security_connector *c = (grpc_server_security_connector *)sc;
+  gpr_mu_destroy(&c->mu);
   gpr_free(sc);
 }
 
@@ -298,49 +308,52 @@
 }
 
 static void fake_channel_do_handshake(grpc_exec_ctx *exec_ctx,
-                                      grpc_security_connector *sc,
+                                      grpc_channel_security_connector *sc,
                                       grpc_endpoint *nonsecure_endpoint,
                                       grpc_security_handshake_done_cb cb,
                                       void *user_data) {
-  grpc_do_security_handshake(exec_ctx, tsi_create_fake_handshaker(1), sc,
-                             nonsecure_endpoint, cb, user_data);
+  grpc_do_security_handshake(exec_ctx, tsi_create_fake_handshaker(1), &sc->base,
+                             true, nonsecure_endpoint, cb, user_data);
 }
 
 static void fake_server_do_handshake(grpc_exec_ctx *exec_ctx,
-                                     grpc_security_connector *sc,
+                                     grpc_server_security_connector *sc,
+                                     grpc_tcp_server_acceptor *acceptor,
                                      grpc_endpoint *nonsecure_endpoint,
                                      grpc_security_handshake_done_cb cb,
                                      void *user_data) {
-  grpc_do_security_handshake(exec_ctx, tsi_create_fake_handshaker(0), sc,
-                             nonsecure_endpoint, cb, user_data);
+  grpc_do_security_handshake(exec_ctx, tsi_create_fake_handshaker(0), &sc->base,
+                             false, nonsecure_endpoint, cb, user_data);
 }
 
 static grpc_security_connector_vtable fake_channel_vtable = {
-    fake_channel_destroy, fake_channel_do_handshake, fake_check_peer};
+    fake_channel_destroy, fake_check_peer};
 
-static grpc_security_connector_vtable fake_server_vtable = {
-    fake_server_destroy, fake_server_do_handshake, fake_check_peer};
+static grpc_security_connector_vtable fake_server_vtable = {fake_server_destroy,
+                                                            fake_check_peer};
 
 grpc_channel_security_connector *grpc_fake_channel_security_connector_create(
     grpc_call_credentials *request_metadata_creds) {
   grpc_channel_security_connector *c = gpr_malloc(sizeof(*c));
   memset(c, 0, sizeof(*c));
   gpr_ref_init(&c->base.refcount, 1);
-  c->base.is_client_side = 1;
   c->base.url_scheme = GRPC_FAKE_SECURITY_URL_SCHEME;
   c->base.vtable = &fake_channel_vtable;
   c->request_metadata_creds = grpc_call_credentials_ref(request_metadata_creds);
   c->check_call_host = fake_channel_check_call_host;
+  c->do_handshake = fake_channel_do_handshake;
   return c;
 }
 
-grpc_security_connector *grpc_fake_server_security_connector_create(void) {
-  grpc_security_connector *c = gpr_malloc(sizeof(grpc_security_connector));
-  memset(c, 0, sizeof(grpc_security_connector));
-  gpr_ref_init(&c->refcount, 1);
-  c->is_client_side = 0;
-  c->vtable = &fake_server_vtable;
-  c->url_scheme = GRPC_FAKE_SECURITY_URL_SCHEME;
+grpc_server_security_connector *grpc_fake_server_security_connector_create(
+    void) {
+  grpc_server_security_connector *c =
+      gpr_malloc(sizeof(grpc_server_security_connector));
+  memset(c, 0, sizeof(*c));
+  gpr_ref_init(&c->base.refcount, 1);
+  c->base.vtable = &fake_server_vtable;
+  c->base.url_scheme = GRPC_FAKE_SECURITY_URL_SCHEME;
+  c->do_handshake = fake_server_do_handshake;
   gpr_mu_init(&c->mu);
   return c;
 }
@@ -355,7 +368,7 @@
 } grpc_ssl_channel_security_connector;
 
 typedef struct {
-  grpc_security_connector base;
+  grpc_server_security_connector base;
   tsi_ssl_handshaker_factory *handshaker_factory;
 } grpc_ssl_server_security_connector;
 
@@ -378,12 +391,12 @@
   if (c->handshaker_factory != NULL) {
     tsi_ssl_handshaker_factory_destroy(c->handshaker_factory);
   }
-  gpr_mu_destroy(&sc->mu);
+  gpr_mu_destroy(&c->base.mu);
   gpr_free(sc);
 }
 
 static grpc_security_status ssl_create_handshaker(
-    tsi_ssl_handshaker_factory *handshaker_factory, int is_client,
+    tsi_ssl_handshaker_factory *handshaker_factory, bool is_client,
     const char *peer_name, tsi_handshaker **handshaker) {
   tsi_result result = TSI_OK;
   if (handshaker_factory == NULL) return GRPC_SECURITY_ERROR;
@@ -398,7 +411,7 @@
 }
 
 static void ssl_channel_do_handshake(grpc_exec_ctx *exec_ctx,
-                                     grpc_security_connector *sc,
+                                     grpc_channel_security_connector *sc,
                                      grpc_endpoint *nonsecure_endpoint,
                                      grpc_security_handshake_done_cb cb,
                                      void *user_data) {
@@ -406,20 +419,21 @@
       (grpc_ssl_channel_security_connector *)sc;
   tsi_handshaker *handshaker;
   grpc_security_status status = ssl_create_handshaker(
-      c->handshaker_factory, 1,
+      c->handshaker_factory, true,
       c->overridden_target_name != NULL ? c->overridden_target_name
                                         : c->target_name,
       &handshaker);
   if (status != GRPC_SECURITY_OK) {
     cb(exec_ctx, user_data, status, NULL, NULL);
   } else {
-    grpc_do_security_handshake(exec_ctx, handshaker, sc, nonsecure_endpoint, cb,
-                               user_data);
+    grpc_do_security_handshake(exec_ctx, handshaker, &sc->base, true,
+                               nonsecure_endpoint, cb, user_data);
   }
 }
 
 static void ssl_server_do_handshake(grpc_exec_ctx *exec_ctx,
-                                    grpc_security_connector *sc,
+                                    grpc_server_security_connector *sc,
+                                    grpc_tcp_server_acceptor *acceptor,
                                     grpc_endpoint *nonsecure_endpoint,
                                     grpc_security_handshake_done_cb cb,
                                     void *user_data) {
@@ -427,12 +441,12 @@
       (grpc_ssl_server_security_connector *)sc;
   tsi_handshaker *handshaker;
   grpc_security_status status =
-      ssl_create_handshaker(c->handshaker_factory, 0, NULL, &handshaker);
+      ssl_create_handshaker(c->handshaker_factory, false, NULL, &handshaker);
   if (status != GRPC_SECURITY_OK) {
     cb(exec_ctx, user_data, status, NULL, NULL);
   } else {
-    grpc_do_security_handshake(exec_ctx, handshaker, sc, nonsecure_endpoint, cb,
-                               user_data);
+    grpc_do_security_handshake(exec_ctx, handshaker, &sc->base, false,
+                               nonsecure_endpoint, cb, user_data);
   }
 }
 
@@ -603,10 +617,10 @@
 }
 
 static grpc_security_connector_vtable ssl_channel_vtable = {
-    ssl_channel_destroy, ssl_channel_do_handshake, ssl_channel_check_peer};
+    ssl_channel_destroy, ssl_channel_check_peer};
 
 static grpc_security_connector_vtable ssl_server_vtable = {
-    ssl_server_destroy, ssl_server_do_handshake, ssl_server_check_peer};
+    ssl_server_destroy, ssl_server_check_peer};
 
 static gpr_slice compute_default_pem_root_certs_once(void) {
   gpr_slice result = gpr_empty_slice();
@@ -700,11 +714,11 @@
 
   gpr_ref_init(&c->base.base.refcount, 1);
   c->base.base.vtable = &ssl_channel_vtable;
-  c->base.base.is_client_side = 1;
   c->base.base.url_scheme = GRPC_SSL_URL_SCHEME;
   c->base.request_metadata_creds =
       grpc_call_credentials_ref(request_metadata_creds);
   c->base.check_call_host = ssl_channel_check_call_host;
+  c->base.do_handshake = ssl_channel_do_handshake;
   gpr_split_host_port(target_name, &c->target_name, &port);
   gpr_free(port);
   if (overridden_target_name != NULL) {
@@ -735,7 +749,7 @@
 }
 
 grpc_security_status grpc_ssl_server_security_connector_create(
-    const grpc_ssl_server_config *config, grpc_security_connector **sc) {
+    const grpc_ssl_server_config *config, grpc_server_security_connector **sc) {
   size_t num_alpn_protocols = grpc_chttp2_num_alpn_versions();
   const unsigned char **alpn_protocol_strings =
       gpr_malloc(sizeof(const char *) * num_alpn_protocols);
@@ -759,9 +773,9 @@
   c = gpr_malloc(sizeof(grpc_ssl_server_security_connector));
   memset(c, 0, sizeof(grpc_ssl_server_security_connector));
 
-  gpr_ref_init(&c->base.refcount, 1);
-  c->base.url_scheme = GRPC_SSL_URL_SCHEME;
-  c->base.vtable = &ssl_server_vtable;
+  gpr_ref_init(&c->base.base.refcount, 1);
+  c->base.base.url_scheme = GRPC_SSL_URL_SCHEME;
+  c->base.base.vtable = &ssl_server_vtable;
   result = tsi_create_ssl_server_handshaker_factory(
       (const unsigned char **)config->pem_private_keys,
       config->pem_private_keys_sizes,
@@ -774,11 +788,12 @@
   if (result != TSI_OK) {
     gpr_log(GPR_ERROR, "Handshaker factory creation failed with %s.",
             tsi_result_to_string(result));
-    ssl_server_destroy(&c->base);
+    ssl_server_destroy(&c->base.base);
     *sc = NULL;
     goto error;
   }
   gpr_mu_init(&c->base.mu);
+  c->base.do_handshake = ssl_server_do_handshake;
   *sc = &c->base;
   gpr_free((void *)alpn_protocol_strings);
   gpr_free(alpn_protocol_string_lengths);
diff --git a/src/core/security/security_connector.h b/src/core/security/security_connector.h
index 39df782..1e35d3f 100644
--- a/src/core/security/security_connector.h
+++ b/src/core/security/security_connector.h
@@ -36,6 +36,7 @@
 
 #include <grpc/grpc_security.h>
 #include "src/core/iomgr/endpoint.h"
+#include "src/core/iomgr/tcp_server.h"
 #include "src/core/tsi/transport_security_interface.h"
 
 /* --- status enum. --- */
@@ -68,9 +69,6 @@
 
 typedef struct {
   void (*destroy)(grpc_security_connector *sc);
-  void (*do_handshake)(grpc_exec_ctx *exec_ctx, grpc_security_connector *sc,
-                       grpc_endpoint *nonsecure_endpoint,
-                       grpc_security_handshake_done_cb cb, void *user_data);
   void (*check_peer)(grpc_exec_ctx *exec_ctx, grpc_security_connector *sc,
                      tsi_peer peer, grpc_security_peer_check_cb cb,
                      void *user_data);
@@ -84,13 +82,7 @@
 struct grpc_security_connector {
   const grpc_security_connector_vtable *vtable;
   gpr_refcount refcount;
-  int is_client_side;
   const char *url_scheme;
-  /* Used on server side only. */
-  /* TODO(yangg): Create a grpc_server_security_connector with these. */
-  gpr_mu mu;
-  grpc_security_connector_handshake_list *handshaking_handshakes;
-  const grpc_channel_args *channel_args;
 };
 
 /* Refcounting. */
@@ -113,13 +105,6 @@
 void grpc_security_connector_unref(grpc_security_connector *policy);
 #endif
 
-/* Handshake. */
-void grpc_security_connector_do_handshake(grpc_exec_ctx *exec_ctx,
-                                          grpc_security_connector *connector,
-                                          grpc_endpoint *nonsecure_endpoint,
-                                          grpc_security_handshake_done_cb cb,
-                                          void *user_data);
-
 /* Check the peer. Callee takes ownership of the peer object.
    The callback will include the resulting auth_context. */
 void grpc_security_connector_check_peer(grpc_exec_ctx *exec_ctx,
@@ -128,9 +113,6 @@
                                         grpc_security_peer_check_cb cb,
                                         void *user_data);
 
-void grpc_security_connector_shutdown(grpc_exec_ctx *exec_ctx,
-                                      grpc_security_connector *connector);
-
 /* Util to encapsulate the connector in a channel arg. */
 grpc_arg grpc_security_connector_to_arg(grpc_security_connector *sc);
 
@@ -153,12 +135,16 @@
                                                  grpc_security_status status);
 
 struct grpc_channel_security_connector {
-  grpc_security_connector base; /* requires is_client_side to be non 0. */
+  grpc_security_connector base;
   grpc_call_credentials *request_metadata_creds;
   void (*check_call_host)(grpc_exec_ctx *exec_ctx,
                           grpc_channel_security_connector *sc, const char *host,
                           grpc_auth_context *auth_context,
                           grpc_security_call_host_check_cb cb, void *user_data);
+  void (*do_handshake)(grpc_exec_ctx *exec_ctx,
+                       grpc_channel_security_connector *sc,
+                       grpc_endpoint *nonsecure_endpoint,
+                       grpc_security_handshake_done_cb cb, void *user_data);
 };
 
 /* Checks that the host that will be set for a call is acceptable. */
@@ -167,6 +153,39 @@
     const char *host, grpc_auth_context *auth_context,
     grpc_security_call_host_check_cb cb, void *user_data);
 
+/* Handshake. */
+void grpc_channel_security_connector_do_handshake(
+    grpc_exec_ctx *exec_ctx, grpc_channel_security_connector *connector,
+    grpc_endpoint *nonsecure_endpoint, grpc_security_handshake_done_cb cb,
+    void *user_data);
+
+/* --- server_security_connector object. ---
+
+    A server security connector object represents away to configure the
+    underlying transport security mechanism on the server side.  */
+
+typedef struct grpc_server_security_connector grpc_server_security_connector;
+
+struct grpc_server_security_connector {
+  grpc_security_connector base;
+  gpr_mu mu;
+  grpc_security_connector_handshake_list *handshaking_handshakes;
+  const grpc_channel_args *channel_args;
+  void (*do_handshake)(grpc_exec_ctx *exec_ctx,
+                       grpc_server_security_connector *sc,
+                       grpc_tcp_server_acceptor *acceptor,
+                       grpc_endpoint *nonsecure_endpoint,
+                       grpc_security_handshake_done_cb cb, void *user_data);
+};
+
+void grpc_server_security_connector_do_handshake(
+    grpc_exec_ctx *exec_ctx, grpc_server_security_connector *sc,
+    grpc_tcp_server_acceptor *acceptor, grpc_endpoint *nonsecure_endpoint,
+    grpc_security_handshake_done_cb cb, void *user_data);
+
+void grpc_server_security_connector_shutdown(
+    grpc_exec_ctx *exec_ctx, grpc_server_security_connector *connector);
+
 /* --- Creation security connectors. --- */
 
 /* For TESTING ONLY!
@@ -176,7 +195,8 @@
 
 /* For TESTING ONLY!
    Creates a fake connector that emulates real server security.  */
-grpc_security_connector *grpc_fake_server_security_connector_create(void);
+grpc_server_security_connector *grpc_fake_server_security_connector_create(
+    void);
 
 /* Config for ssl clients. */
 typedef struct {
@@ -231,7 +251,7 @@
   specific error code otherwise.
 */
 grpc_security_status grpc_ssl_server_security_connector_create(
-    const grpc_ssl_server_config *config, grpc_security_connector **sc);
+    const grpc_ssl_server_config *config, grpc_server_security_connector **sc);
 
 /* Util. */
 const tsi_peer_property *tsi_peer_get_property_by_name(const tsi_peer *peer,
diff --git a/src/core/security/server_secure_chttp2.c b/src/core/security/server_secure_chttp2.c
index 84a8833..91547eb 100644
--- a/src/core/security/server_secure_chttp2.c
+++ b/src/core/security/server_secure_chttp2.c
@@ -55,7 +55,7 @@
 typedef struct grpc_server_secure_state {
   grpc_server *server;
   grpc_tcp_server *tcp;
-  grpc_security_connector *sc;
+  grpc_server_security_connector *sc;
   grpc_server_credentials *creds;
   int is_shutdown;
   gpr_mu mu;
@@ -74,7 +74,7 @@
     gpr_mu_lock(&state->mu);
     gpr_mu_unlock(&state->mu);
     /* clean up */
-    GRPC_SECURITY_CONNECTOR_UNREF(state->sc, "server");
+    GRPC_SECURITY_CONNECTOR_UNREF(&state->sc->base, "server");
     grpc_server_credentials_unref(state->creds);
     gpr_free(state);
   }
@@ -130,8 +130,8 @@
                       grpc_tcp_server_acceptor *acceptor) {
   grpc_server_secure_state *state = statep;
   state_ref(state);
-  grpc_security_connector_do_handshake(exec_ctx, state->sc, tcp,
-                                       on_secure_handshake_done, state);
+  grpc_server_security_connector_do_handshake(
+      exec_ctx, state->sc, acceptor, tcp, on_secure_handshake_done, state);
 }
 
 /* Server callback: start listening on our ports */
@@ -148,7 +148,7 @@
     state->destroy_callback->cb(exec_ctx, state->destroy_callback->cb_arg,
                                 success);
   }
-  grpc_security_connector_shutdown(exec_ctx, state->sc);
+  grpc_server_security_connector_shutdown(exec_ctx, state->sc);
   state_unref(state);
 }
 
@@ -176,7 +176,7 @@
   int port_num = -1;
   int port_temp;
   grpc_security_status status = GRPC_SECURITY_ERROR;
-  grpc_security_connector *sc = NULL;
+  grpc_server_security_connector *sc = NULL;
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
 
   GRPC_API_TRACE(
@@ -256,7 +256,7 @@
     grpc_tcp_server_unref(&exec_ctx, tcp);
   } else {
     if (sc) {
-      GRPC_SECURITY_CONNECTOR_UNREF(sc, "server");
+      GRPC_SECURITY_CONNECTOR_UNREF(&sc->base, "server");
     }
     if (state) {
       gpr_free(state);
diff --git a/src/core/support/env_linux.c b/src/core/support/env_linux.c
index 1ca6fa1..fe51f84 100644
--- a/src/core/support/env_linux.c
+++ b/src/core/support/env_linux.c
@@ -43,7 +43,9 @@
 #include "src/core/support/env.h"
 
 #include <dlfcn.h>
+#include <features.h>
 #include <stdlib.h>
+#include <string.h>
 
 #include <grpc/support/log.h>
 #include <grpc/support/string_util.h>
@@ -60,12 +62,22 @@
   const char *names[] = {"secure_getenv", "__secure_getenv", "getenv"};
   for (size_t i = 0; getenv_func == NULL && i < GPR_ARRAY_SIZE(names); i++) {
     getenv_func = (getenv_type)dlsym(RTLD_DEFAULT, names[i]);
+    if (getenv_func != NULL && strstr(names[i], "secure") == NULL) {
+      gpr_log(GPR_DEBUG,
+              "Warning: insecure environment read function '%s' used",
+              names[i]);
+    }
   }
   char *result = getenv_func(name);
   return result == NULL ? result : gpr_strdup(result);
-#else
+#elif __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 17)
   char *result = secure_getenv(name);
   return result == NULL ? result : gpr_strdup(result);
+#else
+  gpr_log(GPR_DEBUG, "Warning: insecure environment read function '%s' used",
+          "getenv");
+  char *result = getenv(name);
+  return result == NULL ? result : gpr_strdup(result);
 #endif
 }
 
diff --git a/src/core/support/file.c b/src/core/support/load_file.c
similarity index 97%
rename from src/core/support/file.c
rename to src/core/support/load_file.c
index 8c673db..650bd62 100644
--- a/src/core/support/file.c
+++ b/src/core/support/load_file.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,7 +31,7 @@
  *
  */
 
-#include "src/core/support/file.h"
+#include "src/core/support/load_file.h"
 
 #include <errno.h>
 #include <string.h>
diff --git a/src/core/support/file.h b/src/core/support/load_file.h
similarity index 79%
copy from src/core/support/file.h
copy to src/core/support/load_file.h
index d8b7cea..746319a 100644
--- a/src/core/support/file.h
+++ b/src/core/support/load_file.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef GRPC_INTERNAL_CORE_SUPPORT_FILE_H
-#define GRPC_INTERNAL_CORE_SUPPORT_FILE_H
+#ifndef GRPC_INTERNAL_CORE_SUPPORT_LOAD_FILE_H
+#define GRPC_INTERNAL_CORE_SUPPORT_LOAD_FILE_H
 
 #include <stdio.h>
 
@@ -42,22 +42,14 @@
 extern "C" {
 #endif
 
-/* File utility functions */
-
 /* Loads the content of a file into a slice. add_null_terminator will add
    a NULL terminator if non-zero. The success parameter, if not NULL,
    will be set to 1 in case of success and 0 in case of failure. */
 gpr_slice gpr_load_file(const char *filename, int add_null_terminator,
                         int *success);
 
-/* Creates a temporary file from a prefix.
-   If tmp_filename is not NULL, *tmp_filename is assigned the name of the
-   created file and it is the responsibility of the caller to gpr_free it
-   unless an error occurs in which case it will be set to NULL. */
-FILE *gpr_tmpfile(const char *prefix, char **tmp_filename);
-
 #ifdef __cplusplus
 }
 #endif
 
-#endif /* GRPC_INTERNAL_CORE_SUPPORT_FILE_H */
+#endif /* GRPC_INTERNAL_CORE_SUPPORT_LOAD_FILE_H */
diff --git a/src/core/support/sync.c b/src/core/support/sync.c
index d368422..69e3e39 100644
--- a/src/core/support/sync.c
+++ b/src/core/support/sync.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -98,6 +98,11 @@
 
 void gpr_ref(gpr_refcount *r) { gpr_atm_no_barrier_fetch_add(&r->count, 1); }
 
+void gpr_ref_non_zero(gpr_refcount *r) {
+  gpr_atm prior = gpr_atm_no_barrier_fetch_add(&r->count, 1);
+  GPR_ASSERT(prior > 0);
+}
+
 void gpr_refn(gpr_refcount *r, int n) {
   gpr_atm_no_barrier_fetch_add(&r->count, n);
 }
diff --git a/src/core/support/file.h b/src/core/support/tmpfile.h
similarity index 79%
rename from src/core/support/file.h
rename to src/core/support/tmpfile.h
index d8b7cea..cecc71e 100644
--- a/src/core/support/file.h
+++ b/src/core/support/tmpfile.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef GRPC_INTERNAL_CORE_SUPPORT_FILE_H
-#define GRPC_INTERNAL_CORE_SUPPORT_FILE_H
+#ifndef GRPC_INTERNAL_CORE_SUPPORT_TMPFILE_H
+#define GRPC_INTERNAL_CORE_SUPPORT_TMPFILE_H
 
 #include <stdio.h>
 
@@ -42,14 +42,6 @@
 extern "C" {
 #endif
 
-/* File utility functions */
-
-/* Loads the content of a file into a slice. add_null_terminator will add
-   a NULL terminator if non-zero. The success parameter, if not NULL,
-   will be set to 1 in case of success and 0 in case of failure. */
-gpr_slice gpr_load_file(const char *filename, int add_null_terminator,
-                        int *success);
-
 /* Creates a temporary file from a prefix.
    If tmp_filename is not NULL, *tmp_filename is assigned the name of the
    created file and it is the responsibility of the caller to gpr_free it
@@ -60,4 +52,4 @@
 }
 #endif
 
-#endif /* GRPC_INTERNAL_CORE_SUPPORT_FILE_H */
+#endif /* GRPC_INTERNAL_CORE_SUPPORT_TMPFILE_H */
diff --git a/src/core/support/file_posix.c b/src/core/support/tmpfile_posix.c
similarity index 97%
rename from src/core/support/file_posix.c
rename to src/core/support/tmpfile_posix.c
index c11c071..b16eeac 100644
--- a/src/core/support/file_posix.c
+++ b/src/core/support/tmpfile_posix.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -35,7 +35,7 @@
 
 #ifdef GPR_POSIX_FILE
 
-#include "src/core/support/file.h"
+#include "src/core/support/tmpfile.h"
 
 #include <errno.h>
 #include <stdlib.h>
diff --git a/src/core/support/file_win32.c b/src/core/support/tmpfile_win32.c
similarity index 97%
rename from src/core/support/file_win32.c
rename to src/core/support/tmpfile_win32.c
index 355744f..3000f00 100644
--- a/src/core/support/file_win32.c
+++ b/src/core/support/tmpfile_win32.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -44,8 +44,8 @@
 #include <grpc/support/log.h>
 #include <grpc/support/string_util.h>
 
-#include "src/core/support/file.h"
 #include "src/core/support/string_win32.h"
+#include "src/core/support/tmpfile.h"
 
 FILE *gpr_tmpfile(const char *prefix, char **tmp_filename_out) {
   FILE *result = NULL;
diff --git a/src/core/surface/alarm.c b/src/core/surface/alarm.c
index fb496f6..8169ede 100644
--- a/src/core/surface/alarm.c
+++ b/src/core/surface/alarm.c
@@ -64,8 +64,9 @@
   alarm->tag = tag;
 
   grpc_cq_begin_op(cq, tag);
-  grpc_timer_init(&exec_ctx, &alarm->alarm, deadline, alarm_cb, alarm,
-                  gpr_now(GPR_CLOCK_MONOTONIC));
+  grpc_timer_init(&exec_ctx, &alarm->alarm,
+                  gpr_convert_clock_type(deadline, GPR_CLOCK_MONOTONIC),
+                  alarm_cb, alarm, gpr_now(GPR_CLOCK_MONOTONIC));
   grpc_exec_ctx_finish(&exec_ctx);
   return alarm;
 }
diff --git a/src/core/surface/completion_queue.c b/src/core/surface/completion_queue.c
index 75298eb..f6a95eb 100644
--- a/src/core/surface/completion_queue.c
+++ b/src/core/surface/completion_queue.c
@@ -36,26 +36,29 @@
 #include <stdio.h>
 #include <string.h>
 
-#include "src/core/iomgr/timer.h"
-#include "src/core/iomgr/pollset.h"
-#include "src/core/support/string.h"
-#include "src/core/surface/api_trace.h"
-#include "src/core/surface/call.h"
-#include "src/core/surface/event_string.h"
-#include "src/core/surface/surface_trace.h"
-#include "src/core/profiling/timers.h"
 #include <grpc/support/alloc.h>
 #include <grpc/support/atm.h>
 #include <grpc/support/log.h>
 #include <grpc/support/time.h>
 
+#include "src/core/iomgr/pollset.h"
+#include "src/core/iomgr/timer.h"
+#include "src/core/profiling/timers.h"
+#include "src/core/support/string.h"
+#include "src/core/surface/api_trace.h"
+#include "src/core/surface/call.h"
+#include "src/core/surface/event_string.h"
+#include "src/core/surface/surface_trace.h"
+
 typedef struct {
-  grpc_pollset_worker *worker;
+  grpc_pollset_worker **worker;
   void *tag;
 } plucker;
 
 /* Completion queue structure */
 struct grpc_completion_queue {
+  /** owned by pollset */
+  gpr_mu *mu;
   /** completed events */
   grpc_cq_completion completed_head;
   grpc_cq_completion *completed_tail;
@@ -63,8 +66,6 @@
   gpr_refcount pending_events;
   /** Once owning_refs drops to zero, we will destroy the cq */
   gpr_refcount owning_refs;
-  /** the set of low level i/o things that concern this cq */
-  grpc_pollset pollset;
   /** 0 initially, 1 once we've begun shutting down */
   int shutdown;
   int shutdown_called;
@@ -82,6 +83,8 @@
   grpc_completion_queue *next_free;
 };
 
+#define POLLSET_FROM_CQ(cq) ((grpc_pollset *)(cq + 1))
+
 static gpr_mu g_freelist_mu;
 grpc_completion_queue *g_freelist;
 
@@ -94,7 +97,7 @@
   gpr_mu_destroy(&g_freelist_mu);
   while (g_freelist) {
     grpc_completion_queue *next = g_freelist->next_free;
-    grpc_pollset_destroy(&g_freelist->pollset);
+    grpc_pollset_destroy(POLLSET_FROM_CQ(g_freelist));
 #ifndef NDEBUG
     gpr_free(g_freelist->outstanding_tags);
 #endif
@@ -124,8 +127,8 @@
   if (g_freelist == NULL) {
     gpr_mu_unlock(&g_freelist_mu);
 
-    cc = gpr_malloc(sizeof(grpc_completion_queue));
-    grpc_pollset_init(&cc->pollset);
+    cc = gpr_malloc(sizeof(grpc_completion_queue) + grpc_pollset_size());
+    grpc_pollset_init(POLLSET_FROM_CQ(cc), &cc->mu);
 #ifndef NDEBUG
     cc->outstanding_tags = NULL;
     cc->outstanding_tag_capacity = 0;
@@ -184,7 +187,7 @@
 #endif
   if (gpr_unref(&cc->owning_refs)) {
     GPR_ASSERT(cc->completed_head.next == (uintptr_t)&cc->completed_head);
-    grpc_pollset_reset(&cc->pollset);
+    grpc_pollset_reset(POLLSET_FROM_CQ(cc));
     gpr_mu_lock(&g_freelist_mu);
     cc->next_free = g_freelist;
     g_freelist = cc;
@@ -194,7 +197,7 @@
 
 void grpc_cq_begin_op(grpc_completion_queue *cc, void *tag) {
 #ifndef NDEBUG
-  gpr_mu_lock(GRPC_POLLSET_MU(&cc->pollset));
+  gpr_mu_lock(cc->mu);
   GPR_ASSERT(!cc->shutdown_called);
   if (cc->outstanding_tag_count == cc->outstanding_tag_capacity) {
     cc->outstanding_tag_capacity = GPR_MAX(4, 2 * cc->outstanding_tag_capacity);
@@ -203,7 +206,7 @@
                                               cc->outstanding_tag_capacity);
   }
   cc->outstanding_tags[cc->outstanding_tag_count++] = tag;
-  gpr_mu_unlock(GRPC_POLLSET_MU(&cc->pollset));
+  gpr_mu_unlock(cc->mu);
 #endif
   gpr_ref(&cc->pending_events);
 }
@@ -231,7 +234,7 @@
   storage->next =
       ((uintptr_t)&cc->completed_head) | ((uintptr_t)(success != 0));
 
-  gpr_mu_lock(GRPC_POLLSET_MU(&cc->pollset));
+  gpr_mu_lock(cc->mu);
 #ifndef NDEBUG
   for (i = 0; i < (int)cc->outstanding_tag_count; i++) {
     if (cc->outstanding_tags[i] == tag) {
@@ -252,12 +255,12 @@
     pluck_worker = NULL;
     for (i = 0; i < cc->num_pluckers; i++) {
       if (cc->pluckers[i].tag == tag) {
-        pluck_worker = cc->pluckers[i].worker;
+        pluck_worker = *cc->pluckers[i].worker;
         break;
       }
     }
-    grpc_pollset_kick(&cc->pollset, pluck_worker);
-    gpr_mu_unlock(GRPC_POLLSET_MU(&cc->pollset));
+    grpc_pollset_kick(POLLSET_FROM_CQ(cc), pluck_worker);
+    gpr_mu_unlock(cc->mu);
   } else {
     cc->completed_tail->next =
         ((uintptr_t)storage) | (1u & (uintptr_t)cc->completed_tail->next);
@@ -265,8 +268,9 @@
     GPR_ASSERT(!cc->shutdown);
     GPR_ASSERT(cc->shutdown_called);
     cc->shutdown = 1;
-    grpc_pollset_shutdown(exec_ctx, &cc->pollset, &cc->pollset_shutdown_done);
-    gpr_mu_unlock(GRPC_POLLSET_MU(&cc->pollset));
+    grpc_pollset_shutdown(exec_ctx, POLLSET_FROM_CQ(cc),
+                          &cc->pollset_shutdown_done);
+    gpr_mu_unlock(cc->mu);
   }
 
   GPR_TIMER_END("grpc_cq_end_op", 0);
@@ -275,7 +279,7 @@
 grpc_event grpc_completion_queue_next(grpc_completion_queue *cc,
                                       gpr_timespec deadline, void *reserved) {
   grpc_event ret;
-  grpc_pollset_worker worker;
+  grpc_pollset_worker *worker = NULL;
   int first_loop = 1;
   gpr_timespec now;
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
@@ -294,7 +298,7 @@
   deadline = gpr_convert_clock_type(deadline, GPR_CLOCK_MONOTONIC);
 
   GRPC_CQ_INTERNAL_REF(cc, "next");
-  gpr_mu_lock(GRPC_POLLSET_MU(&cc->pollset));
+  gpr_mu_lock(cc->mu);
   for (;;) {
     if (cc->completed_tail != &cc->completed_head) {
       grpc_cq_completion *c = (grpc_cq_completion *)cc->completed_head.next;
@@ -302,7 +306,7 @@
       if (c == cc->completed_tail) {
         cc->completed_tail = &cc->completed_head;
       }
-      gpr_mu_unlock(GRPC_POLLSET_MU(&cc->pollset));
+      gpr_mu_unlock(cc->mu);
       ret.type = GRPC_OP_COMPLETE;
       ret.success = c->next & 1u;
       ret.tag = c->tag;
@@ -310,20 +314,34 @@
       break;
     }
     if (cc->shutdown) {
-      gpr_mu_unlock(GRPC_POLLSET_MU(&cc->pollset));
+      gpr_mu_unlock(cc->mu);
       memset(&ret, 0, sizeof(ret));
       ret.type = GRPC_QUEUE_SHUTDOWN;
       break;
     }
     now = gpr_now(GPR_CLOCK_MONOTONIC);
     if (!first_loop && gpr_time_cmp(now, deadline) >= 0) {
-      gpr_mu_unlock(GRPC_POLLSET_MU(&cc->pollset));
+      gpr_mu_unlock(cc->mu);
       memset(&ret, 0, sizeof(ret));
       ret.type = GRPC_QUEUE_TIMEOUT;
       break;
     }
     first_loop = 0;
-    grpc_pollset_work(&exec_ctx, &cc->pollset, &worker, now, deadline);
+    /* Check alarms - these are a global resource so we just ping
+       each time through on every pollset.
+       May update deadline to ensure timely wakeups.
+       TODO(ctiller): can this work be localized? */
+    gpr_timespec iteration_deadline = deadline;
+    if (grpc_timer_check(&exec_ctx, now, &iteration_deadline)) {
+      GPR_TIMER_MARK("alarm_triggered", 0);
+      gpr_mu_unlock(cc->mu);
+      grpc_exec_ctx_flush(&exec_ctx);
+      gpr_mu_lock(cc->mu);
+      continue;
+    } else {
+      grpc_pollset_work(&exec_ctx, POLLSET_FROM_CQ(cc), &worker, now,
+                        iteration_deadline);
+    }
   }
   GRPC_SURFACE_TRACE_RETURNED_EVENT(cc, &ret);
   GRPC_CQ_INTERNAL_UNREF(cc, "next");
@@ -335,7 +353,7 @@
 }
 
 static int add_plucker(grpc_completion_queue *cc, void *tag,
-                       grpc_pollset_worker *worker) {
+                       grpc_pollset_worker **worker) {
   if (cc->num_pluckers == GRPC_MAX_COMPLETION_QUEUE_PLUCKERS) {
     return 0;
   }
@@ -346,7 +364,7 @@
 }
 
 static void del_plucker(grpc_completion_queue *cc, void *tag,
-                        grpc_pollset_worker *worker) {
+                        grpc_pollset_worker **worker) {
   int i;
   for (i = 0; i < cc->num_pluckers; i++) {
     if (cc->pluckers[i].tag == tag && cc->pluckers[i].worker == worker) {
@@ -363,7 +381,7 @@
   grpc_event ret;
   grpc_cq_completion *c;
   grpc_cq_completion *prev;
-  grpc_pollset_worker worker;
+  grpc_pollset_worker *worker = NULL;
   gpr_timespec now;
   int first_loop = 1;
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
@@ -382,7 +400,7 @@
   deadline = gpr_convert_clock_type(deadline, GPR_CLOCK_MONOTONIC);
 
   GRPC_CQ_INTERNAL_REF(cc, "pluck");
-  gpr_mu_lock(GRPC_POLLSET_MU(&cc->pollset));
+  gpr_mu_lock(cc->mu);
   for (;;) {
     prev = &cc->completed_head;
     while ((c = (grpc_cq_completion *)(prev->next & ~(uintptr_t)1)) !=
@@ -392,7 +410,7 @@
         if (c == cc->completed_tail) {
           cc->completed_tail = prev;
         }
-        gpr_mu_unlock(GRPC_POLLSET_MU(&cc->pollset));
+        gpr_mu_unlock(cc->mu);
         ret.type = GRPC_OP_COMPLETE;
         ret.success = c->next & 1u;
         ret.tag = c->tag;
@@ -402,7 +420,7 @@
       prev = c;
     }
     if (cc->shutdown) {
-      gpr_mu_unlock(GRPC_POLLSET_MU(&cc->pollset));
+      gpr_mu_unlock(cc->mu);
       memset(&ret, 0, sizeof(ret));
       ret.type = GRPC_QUEUE_SHUTDOWN;
       break;
@@ -412,7 +430,7 @@
               "Too many outstanding grpc_completion_queue_pluck calls: maximum "
               "is %d",
               GRPC_MAX_COMPLETION_QUEUE_PLUCKERS);
-      gpr_mu_unlock(GRPC_POLLSET_MU(&cc->pollset));
+      gpr_mu_unlock(cc->mu);
       memset(&ret, 0, sizeof(ret));
       /* TODO(ctiller): should we use a different result here */
       ret.type = GRPC_QUEUE_TIMEOUT;
@@ -421,13 +439,26 @@
     now = gpr_now(GPR_CLOCK_MONOTONIC);
     if (!first_loop && gpr_time_cmp(now, deadline) >= 0) {
       del_plucker(cc, tag, &worker);
-      gpr_mu_unlock(GRPC_POLLSET_MU(&cc->pollset));
+      gpr_mu_unlock(cc->mu);
       memset(&ret, 0, sizeof(ret));
       ret.type = GRPC_QUEUE_TIMEOUT;
       break;
     }
     first_loop = 0;
-    grpc_pollset_work(&exec_ctx, &cc->pollset, &worker, now, deadline);
+    /* Check alarms - these are a global resource so we just ping
+       each time through on every pollset.
+       May update deadline to ensure timely wakeups.
+       TODO(ctiller): can this work be localized? */
+    gpr_timespec iteration_deadline = deadline;
+    if (grpc_timer_check(&exec_ctx, now, &iteration_deadline)) {
+      GPR_TIMER_MARK("alarm_triggered", 0);
+      gpr_mu_unlock(cc->mu);
+      grpc_exec_ctx_flush(&exec_ctx);
+      gpr_mu_lock(cc->mu);
+    } else {
+      grpc_pollset_work(&exec_ctx, POLLSET_FROM_CQ(cc), &worker, now,
+                        iteration_deadline);
+    }
     del_plucker(cc, tag, &worker);
   }
 done:
@@ -446,9 +477,9 @@
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   GPR_TIMER_BEGIN("grpc_completion_queue_shutdown", 0);
   GRPC_API_TRACE("grpc_completion_queue_shutdown(cc=%p)", 1, (cc));
-  gpr_mu_lock(GRPC_POLLSET_MU(&cc->pollset));
+  gpr_mu_lock(cc->mu);
   if (cc->shutdown_called) {
-    gpr_mu_unlock(GRPC_POLLSET_MU(&cc->pollset));
+    gpr_mu_unlock(cc->mu);
     GPR_TIMER_END("grpc_completion_queue_shutdown", 0);
     return;
   }
@@ -456,9 +487,10 @@
   if (gpr_unref(&cc->pending_events)) {
     GPR_ASSERT(!cc->shutdown);
     cc->shutdown = 1;
-    grpc_pollset_shutdown(&exec_ctx, &cc->pollset, &cc->pollset_shutdown_done);
+    grpc_pollset_shutdown(&exec_ctx, POLLSET_FROM_CQ(cc),
+                          &cc->pollset_shutdown_done);
   }
-  gpr_mu_unlock(GRPC_POLLSET_MU(&cc->pollset));
+  gpr_mu_unlock(cc->mu);
   grpc_exec_ctx_finish(&exec_ctx);
   GPR_TIMER_END("grpc_completion_queue_shutdown", 0);
 }
@@ -472,7 +504,7 @@
 }
 
 grpc_pollset *grpc_cq_pollset(grpc_completion_queue *cc) {
-  return &cc->pollset;
+  return POLLSET_FROM_CQ(cc);
 }
 
 void grpc_cq_mark_server_cq(grpc_completion_queue *cc) { cc->is_server_cq = 1; }
diff --git a/src/core/surface/secure_channel_create.c b/src/core/surface/secure_channel_create.c
index 9c04426..aadfac4 100644
--- a/src/core/surface/secure_channel_create.c
+++ b/src/core/surface/secure_channel_create.c
@@ -130,9 +130,9 @@
 static void on_initial_connect_string_sent(grpc_exec_ctx *exec_ctx, void *arg,
                                            bool success) {
   connector *c = arg;
-  grpc_security_connector_do_handshake(exec_ctx, &c->security_connector->base,
-                                       c->connecting_endpoint,
-                                       on_secure_handshake_done, c);
+  grpc_channel_security_connector_do_handshake(exec_ctx, c->security_connector,
+                                               c->connecting_endpoint,
+                                               on_secure_handshake_done, c);
 }
 
 static void connected(grpc_exec_ctx *exec_ctx, void *arg, bool success) {
@@ -153,9 +153,8 @@
       grpc_endpoint_write(exec_ctx, tcp, &c->initial_string_buffer,
                           &c->initial_string_sent);
     } else {
-      grpc_security_connector_do_handshake(exec_ctx,
-                                           &c->security_connector->base, tcp,
-                                           on_secure_handshake_done, c);
+      grpc_channel_security_connector_do_handshake(
+          exec_ctx, c->security_connector, tcp, on_secure_handshake_done, c);
     }
   } else {
     memset(c->result, 0, sizeof(*c->result));
diff --git a/src/core/transport/chttp2/internal.h b/src/core/transport/chttp2/internal.h
index 0e1e2c4..891aad6 100644
--- a/src/core/transport/chttp2/internal.h
+++ b/src/core/transport/chttp2/internal.h
@@ -417,7 +417,7 @@
   /** HTTP2 stream id for this stream, or zero if one has not been assigned */
   uint32_t id;
   uint8_t fetching;
-  uint8_t sent_initial_metadata;
+  bool sent_initial_metadata;
   uint8_t sent_message;
   uint8_t sent_trailing_metadata;
   uint8_t read_closed;
@@ -485,7 +485,8 @@
 
 /** Someone is unlocking the transport mutex: check to see if writes
     are required, and schedule them if so */
-int grpc_chttp2_unlocking_check_writes(grpc_chttp2_transport_global *global,
+int grpc_chttp2_unlocking_check_writes(grpc_exec_ctx *exec_ctx,
+                                       grpc_chttp2_transport_global *global,
                                        grpc_chttp2_transport_writing *writing,
                                        int is_parsing);
 void grpc_chttp2_perform_writes(
@@ -508,7 +509,7 @@
                                grpc_chttp2_transport_global *global,
                                grpc_chttp2_transport_parsing *parsing);
 
-void grpc_chttp2_list_add_writable_stream(
+bool grpc_chttp2_list_add_writable_stream(
     grpc_chttp2_transport_global *transport_global,
     grpc_chttp2_stream_global *stream_global);
 /** Get a writable stream
@@ -518,14 +519,13 @@
     grpc_chttp2_transport_writing *transport_writing,
     grpc_chttp2_stream_global **stream_global,
     grpc_chttp2_stream_writing **stream_writing);
-void grpc_chttp2_list_remove_writable_stream(
+bool grpc_chttp2_list_remove_writable_stream(
     grpc_chttp2_transport_global *transport_global,
-    grpc_chttp2_stream_global *stream_global);
+    grpc_chttp2_stream_global *stream_global) GRPC_MUST_USE_RESULT;
 
-/* returns 1 if stream added, 0 if it was already present */
-int grpc_chttp2_list_add_writing_stream(
+void grpc_chttp2_list_add_writing_stream(
     grpc_chttp2_transport_writing *transport_writing,
-    grpc_chttp2_stream_writing *stream_writing) GRPC_MUST_USE_RESULT;
+    grpc_chttp2_stream_writing *stream_writing);
 int grpc_chttp2_list_have_writing_streams(
     grpc_chttp2_transport_writing *transport_writing);
 int grpc_chttp2_list_pop_writing_stream(
@@ -568,8 +568,12 @@
     grpc_chttp2_transport_writing *transport_writing,
     grpc_chttp2_stream_writing *stream_writing);
 void grpc_chttp2_list_flush_writing_stalled_by_transport(
-    grpc_chttp2_transport_writing *transport_writing, bool is_window_available);
+    grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_writing *transport_writing,
+    bool is_window_available);
 
+void grpc_chttp2_list_add_stalled_by_transport(
+    grpc_chttp2_transport_writing *transport_writing,
+    grpc_chttp2_stream_writing *stream_writing);
 int grpc_chttp2_list_pop_stalled_by_transport(
     grpc_chttp2_transport_global *transport_global,
     grpc_chttp2_stream_global **stream_global);
@@ -765,4 +769,9 @@
                           grpc_chttp2_transport_parsing *parsing,
                           const uint8_t *opaque_8bytes);
 
+/** add a ref to the stream and add it to the writable list;
+    ref will be dropped in writing.c */
+void grpc_chttp2_become_writable(grpc_chttp2_transport_global *transport_global,
+                                 grpc_chttp2_stream_global *stream_global);
+
 #endif
diff --git a/src/core/transport/chttp2/parsing.c b/src/core/transport/chttp2/parsing.c
index 8fdebd7..0516f39 100644
--- a/src/core/transport/chttp2/parsing.c
+++ b/src/core/transport/chttp2/parsing.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -149,7 +149,7 @@
   if (was_zero && !is_zero) {
     while (grpc_chttp2_list_pop_stalled_by_transport(transport_global,
                                                      &stream_global)) {
-      grpc_chttp2_list_add_writable_stream(transport_global, stream_global);
+      grpc_chttp2_become_writable(transport_global, stream_global);
     }
   }
 
@@ -178,7 +178,7 @@
                                  outgoing_window);
     is_zero = stream_global->outgoing_window <= 0;
     if (was_zero && !is_zero) {
-      grpc_chttp2_list_add_writable_stream(transport_global, stream_global);
+      grpc_chttp2_become_writable(transport_global, stream_global);
     }
 
     stream_global->max_recv_bytes -= (uint32_t)GPR_MIN(
diff --git a/src/core/transport/chttp2/stream_lists.c b/src/core/transport/chttp2/stream_lists.c
index 2f31a47..60fe735 100644
--- a/src/core/transport/chttp2/stream_lists.c
+++ b/src/core/transport/chttp2/stream_lists.c
@@ -100,11 +100,14 @@
   }
 }
 
-static void stream_list_maybe_remove(grpc_chttp2_transport *t,
+static bool stream_list_maybe_remove(grpc_chttp2_transport *t,
                                      grpc_chttp2_stream *s,
                                      grpc_chttp2_stream_list_id id) {
   if (s->included[id]) {
     stream_list_remove(t, s, id);
+    return true;
+  } else {
+    return false;
   }
 }
 
@@ -125,23 +128,24 @@
   s->included[id] = 1;
 }
 
-static int stream_list_add(grpc_chttp2_transport *t, grpc_chttp2_stream *s,
-                           grpc_chttp2_stream_list_id id) {
+static bool stream_list_add(grpc_chttp2_transport *t, grpc_chttp2_stream *s,
+                            grpc_chttp2_stream_list_id id) {
   if (s->included[id]) {
-    return 0;
+    return false;
   }
   stream_list_add_tail(t, s, id);
-  return 1;
+  return true;
 }
 
 /* wrappers for specializations */
 
-void grpc_chttp2_list_add_writable_stream(
+bool grpc_chttp2_list_add_writable_stream(
     grpc_chttp2_transport_global *transport_global,
     grpc_chttp2_stream_global *stream_global) {
   GPR_ASSERT(stream_global->id != 0);
-  stream_list_add(TRANSPORT_FROM_GLOBAL(transport_global),
-                  STREAM_FROM_GLOBAL(stream_global), GRPC_CHTTP2_LIST_WRITABLE);
+  return stream_list_add(TRANSPORT_FROM_GLOBAL(transport_global),
+                         STREAM_FROM_GLOBAL(stream_global),
+                         GRPC_CHTTP2_LIST_WRITABLE);
 }
 
 int grpc_chttp2_list_pop_writable_stream(
@@ -159,20 +163,20 @@
   return r;
 }
 
-void grpc_chttp2_list_remove_writable_stream(
+bool grpc_chttp2_list_remove_writable_stream(
     grpc_chttp2_transport_global *transport_global,
     grpc_chttp2_stream_global *stream_global) {
-  stream_list_maybe_remove(TRANSPORT_FROM_GLOBAL(transport_global),
-                           STREAM_FROM_GLOBAL(stream_global),
-                           GRPC_CHTTP2_LIST_WRITABLE);
+  return stream_list_maybe_remove(TRANSPORT_FROM_GLOBAL(transport_global),
+                                  STREAM_FROM_GLOBAL(stream_global),
+                                  GRPC_CHTTP2_LIST_WRITABLE);
 }
 
-int grpc_chttp2_list_add_writing_stream(
+void grpc_chttp2_list_add_writing_stream(
     grpc_chttp2_transport_writing *transport_writing,
     grpc_chttp2_stream_writing *stream_writing) {
-  return stream_list_add(TRANSPORT_FROM_WRITING(transport_writing),
-                         STREAM_FROM_WRITING(stream_writing),
-                         GRPC_CHTTP2_LIST_WRITING);
+  GPR_ASSERT(stream_list_add(TRANSPORT_FROM_WRITING(transport_writing),
+                             STREAM_FROM_WRITING(stream_writing),
+                             GRPC_CHTTP2_LIST_WRITING));
 }
 
 int grpc_chttp2_list_have_writing_streams(
@@ -316,26 +320,40 @@
 void grpc_chttp2_list_add_writing_stalled_by_transport(
     grpc_chttp2_transport_writing *transport_writing,
     grpc_chttp2_stream_writing *stream_writing) {
-  stream_list_add(TRANSPORT_FROM_WRITING(transport_writing),
-                  STREAM_FROM_WRITING(stream_writing),
+  grpc_chttp2_stream *stream = STREAM_FROM_WRITING(stream_writing);
+  if (!stream->included[GRPC_CHTTP2_LIST_WRITING_STALLED_BY_TRANSPORT]) {
+    GRPC_CHTTP2_STREAM_REF(&stream->global, "chttp2_writing_stalled");
+  }
+  stream_list_add(TRANSPORT_FROM_WRITING(transport_writing), stream,
                   GRPC_CHTTP2_LIST_WRITING_STALLED_BY_TRANSPORT);
 }
 
 void grpc_chttp2_list_flush_writing_stalled_by_transport(
-    grpc_chttp2_transport_writing *transport_writing,
+    grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_writing *transport_writing,
     bool is_window_available) {
   grpc_chttp2_stream *stream;
   grpc_chttp2_transport *transport = TRANSPORT_FROM_WRITING(transport_writing);
   while (stream_list_pop(transport, &stream,
                          GRPC_CHTTP2_LIST_WRITING_STALLED_BY_TRANSPORT)) {
     if (is_window_available) {
-      grpc_chttp2_list_add_writable_stream(&transport->global, &stream->global);
+      grpc_chttp2_become_writable(&transport->global, &stream->global);
     } else {
-      stream_list_add(transport, stream, GRPC_CHTTP2_LIST_STALLED_BY_TRANSPORT);
+      grpc_chttp2_list_add_stalled_by_transport(transport_writing,
+                                                &stream->writing);
     }
+    GRPC_CHTTP2_STREAM_UNREF(exec_ctx, &stream->global,
+                             "chttp2_writing_stalled");
   }
 }
 
+void grpc_chttp2_list_add_stalled_by_transport(
+    grpc_chttp2_transport_writing *transport_writing,
+    grpc_chttp2_stream_writing *stream_writing) {
+  stream_list_add(TRANSPORT_FROM_WRITING(transport_writing),
+                  STREAM_FROM_WRITING(stream_writing),
+                  GRPC_CHTTP2_LIST_STALLED_BY_TRANSPORT);
+}
+
 int grpc_chttp2_list_pop_stalled_by_transport(
     grpc_chttp2_transport_global *transport_global,
     grpc_chttp2_stream_global **stream_global) {
diff --git a/src/core/transport/chttp2/writing.c b/src/core/transport/chttp2/writing.c
index cafecf1..107725c 100644
--- a/src/core/transport/chttp2/writing.c
+++ b/src/core/transport/chttp2/writing.c
@@ -44,7 +44,7 @@
                             grpc_chttp2_transport_writing *transport_writing);
 
 int grpc_chttp2_unlocking_check_writes(
-    grpc_chttp2_transport_global *transport_global,
+    grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_global *transport_global,
     grpc_chttp2_transport_writing *transport_writing, int is_parsing) {
   grpc_chttp2_stream_global *stream_global;
   grpc_chttp2_stream_writing *stream_writing;
@@ -76,14 +76,15 @@
   GRPC_CHTTP2_FLOW_MOVE_TRANSPORT("write", transport_writing, outgoing_window,
                                   transport_global, outgoing_window);
   bool is_window_available = transport_writing->outgoing_window > 0;
-  grpc_chttp2_list_flush_writing_stalled_by_transport(transport_writing,
-                                                      is_window_available);
+  grpc_chttp2_list_flush_writing_stalled_by_transport(
+      exec_ctx, transport_writing, is_window_available);
 
   /* for each grpc_chttp2_stream that's become writable, frame it's data
      (according to available window sizes) and add to the output buffer */
   while (grpc_chttp2_list_pop_writable_stream(
       transport_global, transport_writing, &stream_global, &stream_writing)) {
-    uint8_t sent_initial_metadata;
+    bool sent_initial_metadata = stream_writing->sent_initial_metadata;
+    bool become_writable = false;
 
     stream_writing->id = stream_global->id;
     stream_writing->read_closed = stream_global->read_closed;
@@ -92,16 +93,12 @@
                                  outgoing_window, stream_global,
                                  outgoing_window);
 
-    sent_initial_metadata = stream_writing->sent_initial_metadata;
     if (!sent_initial_metadata && stream_global->send_initial_metadata) {
       stream_writing->send_initial_metadata =
           stream_global->send_initial_metadata;
       stream_global->send_initial_metadata = NULL;
-      if (grpc_chttp2_list_add_writing_stream(transport_writing,
-                                              stream_writing)) {
-        GRPC_CHTTP2_STREAM_REF(stream_global, "chttp2_writing");
-      }
-      sent_initial_metadata = 1;
+      become_writable = true;
+      sent_initial_metadata = true;
     }
     if (sent_initial_metadata) {
       if (stream_global->send_message != NULL) {
@@ -128,23 +125,17 @@
            stream_writing->flow_controlled_buffer.length > 0) &&
           stream_writing->outgoing_window > 0) {
         if (transport_writing->outgoing_window > 0) {
-          if (grpc_chttp2_list_add_writing_stream(transport_writing,
-                                                  stream_writing)) {
-            GRPC_CHTTP2_STREAM_REF(stream_global, "chttp2_writing");
-          }
+          become_writable = true;
         } else {
-          grpc_chttp2_list_add_writing_stalled_by_transport(transport_writing,
-                                                            stream_writing);
+          grpc_chttp2_list_add_stalled_by_transport(transport_writing,
+                                                    stream_writing);
         }
       }
       if (stream_global->send_trailing_metadata) {
         stream_writing->send_trailing_metadata =
             stream_global->send_trailing_metadata;
         stream_global->send_trailing_metadata = NULL;
-        if (grpc_chttp2_list_add_writing_stream(transport_writing,
-                                                stream_writing)) {
-          GRPC_CHTTP2_STREAM_REF(stream_global, "chttp2_writing");
-        }
+        become_writable = true;
       }
     }
 
@@ -153,10 +144,13 @@
       GRPC_CHTTP2_FLOW_MOVE_STREAM("write", transport_global, stream_writing,
                                    announce_window, stream_global,
                                    unannounced_incoming_window_for_writing);
-      if (grpc_chttp2_list_add_writing_stream(transport_writing,
-                                              stream_writing)) {
-        GRPC_CHTTP2_STREAM_REF(stream_global, "chttp2_writing");
-      }
+      become_writable = true;
+    }
+
+    if (become_writable) {
+      grpc_chttp2_list_add_writing_stream(transport_writing, stream_writing);
+    } else {
+      GRPC_CHTTP2_STREAM_UNREF(exec_ctx, stream_global, "chttp2_writing");
     }
   }
 
@@ -310,10 +304,7 @@
          (stream_writing->send_message && !stream_writing->fetching)) &&
         stream_writing->outgoing_window > 0) {
       if (transport_writing->outgoing_window > 0) {
-        if (grpc_chttp2_list_add_writing_stream(transport_writing,
-                                                stream_writing)) {
-          /* do nothing - already reffed */
-        }
+        grpc_chttp2_list_add_writing_stream(transport_writing, stream_writing);
       } else {
         grpc_chttp2_list_add_writing_stalled_by_transport(transport_writing,
                                                           stream_writing);
diff --git a/src/core/transport/chttp2_transport.c b/src/core/transport/chttp2_transport.c
index 617d988..a1ca78d 100644
--- a/src/core/transport/chttp2_transport.c
+++ b/src/core/transport/chttp2_transport.c
@@ -142,7 +142,7 @@
 static void fail_pending_writes(grpc_exec_ctx *exec_ctx,
                                 grpc_chttp2_stream_global *stream_global);
 
-/*
+/*******************************************************************************
  * CONSTRUCTION/DESTRUCTION/REFCOUNTING
  */
 
@@ -521,7 +521,6 @@
                                            s->global.id) == NULL);
   }
 
-  grpc_chttp2_list_remove_writable_stream(&t->global, &s->global);
   grpc_chttp2_list_remove_unannounced_incoming_window_available(&t->global,
                                                                 &s->global);
   grpc_chttp2_list_remove_stalled_by_transport(&t->global, &s->global);
@@ -583,7 +582,7 @@
   return &accepting->parsing;
 }
 
-/*
+/*******************************************************************************
  * LOCK MANAGEMENT
  */
 
@@ -598,7 +597,7 @@
 static void unlock(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t) {
   GPR_TIMER_BEGIN("unlock", 0);
   if (!t->writing_active && !t->closed &&
-      grpc_chttp2_unlocking_check_writes(&t->global, &t->writing,
+      grpc_chttp2_unlocking_check_writes(exec_ctx, &t->global, &t->writing,
                                          t->parsing_active)) {
     t->writing_active = 1;
     REF_TRANSPORT(t, "writing");
@@ -611,10 +610,18 @@
   GPR_TIMER_END("unlock", 0);
 }
 
-/*
+/*******************************************************************************
  * OUTPUT PROCESSING
  */
 
+void grpc_chttp2_become_writable(grpc_chttp2_transport_global *transport_global,
+                                 grpc_chttp2_stream_global *stream_global) {
+  if (!TRANSPORT_FROM_GLOBAL(transport_global)->closed &&
+      grpc_chttp2_list_add_writable_stream(transport_global, stream_global)) {
+    GRPC_CHTTP2_STREAM_REF(stream_global, "chttp2_writing");
+  }
+}
+
 static void push_setting(grpc_chttp2_transport *t, grpc_chttp2_setting_id id,
                          uint32_t value) {
   const grpc_chttp2_setting_parameters *sp =
@@ -732,7 +739,7 @@
         stream_global->id, STREAM_FROM_GLOBAL(stream_global));
     stream_global->in_stream_map = 1;
     transport_global->concurrent_stream_count++;
-    grpc_chttp2_list_add_writable_stream(transport_global, stream_global);
+    grpc_chttp2_become_writable(transport_global, stream_global);
   }
   /* cancel out streams that will never be started */
   while (transport_global->next_stream_id >= MAX_CLIENT_STREAM_ID &&
@@ -821,7 +828,7 @@
         maybe_start_some_streams(exec_ctx, transport_global);
       } else {
         GPR_ASSERT(stream_global->id != 0);
-        grpc_chttp2_list_add_writable_stream(transport_global, stream_global);
+        grpc_chttp2_become_writable(transport_global, stream_global);
       }
     } else {
       grpc_chttp2_complete_closure_step(
@@ -838,7 +845,7 @@
           exec_ctx, &stream_global->send_message_finished, 0);
     } else if (stream_global->id != 0) {
       stream_global->send_message = op->send_message;
-      grpc_chttp2_list_add_writable_stream(transport_global, stream_global);
+      grpc_chttp2_become_writable(transport_global, stream_global);
     }
   }
 
@@ -858,7 +865,7 @@
     } else if (stream_global->id != 0) {
       /* TODO(ctiller): check if there's flow control for any outstanding
          bytes before going writable */
-      grpc_chttp2_list_add_writable_stream(transport_global, stream_global);
+      grpc_chttp2_become_writable(transport_global, stream_global);
     }
   }
 
@@ -999,7 +1006,7 @@
   }
 }
 
-/*
+/*******************************************************************************
  * INPUT PROCESSING
  */
 
@@ -1019,6 +1026,11 @@
       stream_global->recv_initial_metadata_ready = NULL;
     }
     if (stream_global->recv_message_ready != NULL) {
+      while (stream_global->seen_error &&
+             (bs = grpc_chttp2_incoming_frame_queue_pop(
+                  &stream_global->incoming_frames)) != NULL) {
+        grpc_byte_stream_destroy(exec_ctx, bs);
+      }
       if (stream_global->incoming_frames.head != NULL) {
         *stream_global->recv_message = grpc_chttp2_incoming_frame_queue_pop(
             &stream_global->incoming_frames);
@@ -1059,7 +1071,6 @@
   if (!s) {
     s = grpc_chttp2_stream_map_delete(&t->new_stream_map, id);
   }
-  grpc_chttp2_list_remove_writable_stream(&t->global, &s->global);
   GPR_ASSERT(s);
   s->global.in_stream_map = 0;
   if (t->parsing.incoming_stream == &s->parsing) {
@@ -1075,6 +1086,9 @@
   if (grpc_chttp2_unregister_stream(t, s) && t->global.sent_goaway) {
     close_transport_locked(exec_ctx, t);
   }
+  if (grpc_chttp2_list_remove_writable_stream(&t->global, &s->global)) {
+    GRPC_CHTTP2_STREAM_UNREF(exec_ctx, &s->global, "chttp2_writing");
+  }
 
   new_stream_count = grpc_chttp2_stream_map_size(&t->parsing_stream_map) +
                      grpc_chttp2_stream_map_size(&t->new_stream_map);
@@ -1326,7 +1340,7 @@
   is_zero = stream_global->outgoing_window <= 0;
 
   if (was_zero && !is_zero) {
-    grpc_chttp2_list_add_writable_stream(transport_global, stream_global);
+    grpc_chttp2_become_writable(transport_global, stream_global);
   }
 }
 
@@ -1421,7 +1435,7 @@
   GPR_TIMER_END("recv_data", 0);
 }
 
-/*
+/*******************************************************************************
  * CALLBACK LOOP
  */
 
@@ -1435,7 +1449,7 @@
                               state, reason);
 }
 
-/*
+/*******************************************************************************
  * POLLSET STUFF
  */
 
@@ -1463,7 +1477,7 @@
   unlock(exec_ctx, t);
 }
 
-/*
+/*******************************************************************************
  * BYTE STREAM
  */
 
@@ -1503,7 +1517,7 @@
                                    add_max_recv_bytes);
     grpc_chttp2_list_add_unannounced_incoming_window_available(transport_global,
                                                                stream_global);
-    grpc_chttp2_list_add_writable_stream(transport_global, stream_global);
+    grpc_chttp2_become_writable(transport_global, stream_global);
   }
 }
 
@@ -1618,7 +1632,7 @@
   return incoming_byte_stream;
 }
 
-/*
+/*******************************************************************************
  * TRACING
  */
 
@@ -1704,7 +1718,7 @@
   gpr_free(prefix);
 }
 
-/*
+/*******************************************************************************
  * INTEGRATION GLUE
  */
 
diff --git a/src/core/transport/metadata.c b/src/core/transport/metadata.c
index 14912af..807ae07 100644
--- a/src/core/transport/metadata.c
+++ b/src/core/transport/metadata.c
@@ -43,11 +43,13 @@
 #include <grpc/support/log.h>
 #include <grpc/support/string_util.h>
 #include <grpc/support/time.h>
+
 #include "src/core/profiling/timers.h"
 #include "src/core/support/murmur_hash.h"
 #include "src/core/support/string.h"
 #include "src/core/transport/chttp2/bin_encoder.h"
 #include "src/core/transport/static_metadata.h"
+#include "src/core/iomgr/iomgr_internal.h"
 
 /* There are two kinds of mdelem and mdstr instances.
  * Static instances are declared in static_metadata.{h,c} and
@@ -227,6 +229,9 @@
     if (shard->count != 0) {
       gpr_log(GPR_DEBUG, "WARNING: %d metadata elements were leaked",
               shard->count);
+      if (grpc_iomgr_abort_on_leaks()) {
+        abort();
+      }
     }
     gpr_free(shard->elems);
   }
@@ -237,6 +242,9 @@
     if (shard->count != 0) {
       gpr_log(GPR_DEBUG, "WARNING: %d metadata strings were leaked",
               shard->count);
+      if (grpc_iomgr_abort_on_leaks()) {
+        abort();
+      }
     }
     gpr_free(shard->strs);
   }
diff --git a/src/core/transport/transport.c b/src/core/transport/transport.c
index 6e154b6..3b555fa 100644
--- a/src/core/transport/transport.c
+++ b/src/core/transport/transport.c
@@ -45,7 +45,7 @@
 #else
 void grpc_stream_ref(grpc_stream_refcount *refcount) {
 #endif
-  gpr_ref(&refcount->refs);
+  gpr_ref_non_zero(&refcount->refs);
 }
 
 #ifdef GRPC_STREAM_REFCOUNT_DEBUG
diff --git a/src/cpp/common/alarm.cc b/src/cpp/common/alarm.cc
deleted file mode 100644
index a289688..0000000
--- a/src/cpp/common/alarm.cc
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright 2015-2016, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#include <grpc++/alarm.h>
-#include <grpc++/completion_queue.h>
-#include <grpc++/impl/grpc_library.h>
-#include <grpc/grpc.h>
-
-namespace grpc {
-
-static internal::GrpcLibraryInitializer g_gli_initializer;
-Alarm::Alarm(CompletionQueue* cq, gpr_timespec deadline, void* tag)
-    : tag_(tag),
-      alarm_(grpc_alarm_create(cq->cq(), deadline, static_cast<void*>(&tag_))) {
-  g_gli_initializer.summon();
-}
-
-Alarm::~Alarm() { grpc_alarm_destroy(alarm_); }
-
-void Alarm::Cancel() { grpc_alarm_cancel(alarm_); }
-
-}  // namespace grpc
diff --git a/test/cpp/qps/timer.h b/src/cpp/proto/proto_serializer.cc
similarity index 81%
copy from test/cpp/qps/timer.h
copy to src/cpp/proto/proto_serializer.cc
index d1aee1a..3591417 100644
--- a/test/cpp/qps/timer.h
+++ b/src/cpp/proto/proto_serializer.cc
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,27 +31,12 @@
  *
  */
 
-#ifndef TEST_QPS_TIMER_H
-#define TEST_QPS_TIMER_H
+// TODO(dgq): This file is part of a temporary fix to work around codegen
+// issues.
+//
+// This whole file will be removed in the future.
 
-class Timer {
- public:
-  Timer();
+#include <grpc++/impl/proto_utils.h>
 
-  struct Result {
-    double wall;
-    double user;
-    double system;
-  };
-
-  Result Mark() const;
-
-  static double Now();
-
- private:
-  static Result Sample();
-
-  const Result start_;
-};
-
-#endif  // TEST_QPS_TIMER_H
+static grpc::ProtoSerializer proto_serializer;
+grpc::ProtoSerializerInterface* grpc::g_proto_serializer = &proto_serializer;
diff --git a/src/cpp/proto/proto_utils.cc b/src/cpp/proto/proto_utils.cc
index 79e7bf1..a95a290 100644
--- a/src/cpp/proto/proto_utils.cc
+++ b/src/cpp/proto/proto_utils.cc
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -38,7 +38,6 @@
 #include <grpc/grpc.h>
 #include <grpc/byte_buffer.h>
 #include <grpc/byte_buffer_reader.h>
-#include <grpc/support/log.h>
 #include <grpc/support/slice.h>
 #include <grpc/support/slice_buffer.h>
 #include <grpc/support/port_platform.h>
@@ -164,8 +163,8 @@
 
 namespace grpc {
 
-Status SerializeProto(const grpc::protobuf::Message& msg,
-                      grpc_byte_buffer** bp) {
+Status ProtoSerializer::SerializeProto(const grpc::protobuf::Message& msg,
+                                       grpc_byte_buffer** bp) {
   GPR_TIMER_SCOPE("SerializeProto", 0);
   int byte_size = msg.ByteSize();
   if (byte_size <= kMaxBufferLength) {
@@ -183,8 +182,9 @@
   }
 }
 
-Status DeserializeProto(grpc_byte_buffer* buffer, grpc::protobuf::Message* msg,
-                        int max_message_size) {
+Status ProtoSerializer::DeserializeProto(grpc_byte_buffer* buffer,
+                                         grpc::protobuf::Message* msg,
+                                         int max_message_size) {
   GPR_TIMER_SCOPE("DeserializeProto", 0);
   if (!buffer) {
     return Status(StatusCode::INTERNAL, "No payload");
diff --git a/src/cpp/server/server.cc b/src/cpp/server/server.cc
index 0d31140..6d31a60 100644
--- a/src/cpp/server/server.cc
+++ b/src/cpp/server/server.cc
@@ -272,27 +272,25 @@
   grpc_completion_queue* cq_;
 };
 
-static grpc_server* CreateServer(const ChannelArguments& args) {
-  grpc_channel_args channel_args;
-  args.SetChannelArgs(&channel_args);
-  return grpc_server_create(&channel_args, nullptr);
-}
-
 static internal::GrpcLibraryInitializer g_gli_initializer;
 Server::Server(ThreadPoolInterface* thread_pool, bool thread_pool_owned,
-               int max_message_size, const ChannelArguments& args)
+               int max_message_size, ChannelArguments* args)
     : max_message_size_(max_message_size),
       started_(false),
       shutdown_(false),
       num_running_cb_(0),
       sync_methods_(new std::list<SyncRequest>),
       has_generic_service_(false),
-      server_(CreateServer(args)),
+      server_(nullptr),
       thread_pool_(thread_pool),
       thread_pool_owned_(thread_pool_owned) {
   g_gli_initializer.summon();
   gpr_once_init(&g_once_init_callbacks, InitGlobalCallbacks);
   global_callbacks_ = g_callbacks;
+  global_callbacks_->UpdateArguments(args);
+  grpc_channel_args channel_args;
+  args->SetChannelArgs(&channel_args);
+  server_ = grpc_server_create(&channel_args, nullptr);
   grpc_server_register_completion_queue(server_, cq_.cq(), nullptr);
 }
 
diff --git a/src/cpp/server/server_builder.cc b/src/cpp/server/server_builder.cc
index c54cf64..134e5f1 100644
--- a/src/cpp/server/server_builder.cc
+++ b/src/cpp/server/server_builder.cc
@@ -103,7 +103,7 @@
   args.SetInt(GRPC_COMPRESSION_ALGORITHM_STATE_ARG,
               compression_options_.enabled_algorithms_bitset);
   std::unique_ptr<Server> server(
-      new Server(thread_pool.release(), true, max_message_size_, args));
+      new Server(thread_pool.release(), true, max_message_size_, &args));
   for (auto cq = cqs_.begin(); cq != cqs_.end(); ++cq) {
     grpc_server_register_completion_queue(server->server_, (*cq)->cq(),
                                           nullptr);
diff --git a/src/csharp/Grpc.Auth/GoogleAuthInterceptors.cs b/src/csharp/Grpc.Auth/GoogleAuthInterceptors.cs
index f77e9c6..1837f5c 100644
--- a/src/csharp/Grpc.Auth/GoogleAuthInterceptors.cs
+++ b/src/csharp/Grpc.Auth/GoogleAuthInterceptors.cs
@@ -1,6 +1,6 @@
 #region Copyright notice and license
 
-// Copyright 2015, Google Inc.
+// Copyright 2015-2016, Google Inc.
 // All rights reserved.
 //
 // Redistribution and use in source and binary forms, with or without
@@ -71,7 +71,7 @@
         /// <returns>The interceptor.</returns>
         public static AsyncAuthInterceptor FromAccessToken(string accessToken)
         {
-            Preconditions.CheckNotNull(accessToken);
+            GrpcPreconditions.CheckNotNull(accessToken);
             return new AsyncAuthInterceptor(async (context, metadata) =>
             {
                 metadata.Add(CreateBearerTokenHeader(accessToken));
diff --git a/src/csharp/Grpc.Core/AsyncAuthInterceptor.cs b/src/csharp/Grpc.Core/AsyncAuthInterceptor.cs
index 5c9ab04..5ba06d6 100644
--- a/src/csharp/Grpc.Core/AsyncAuthInterceptor.cs
+++ b/src/csharp/Grpc.Core/AsyncAuthInterceptor.cs
@@ -1,6 +1,6 @@
 #region Copyright notice and license
 
-// Copyright 2015, Google Inc.
+// Copyright 2015-2016, Google Inc.
 // All rights reserved.
 //
 // Redistribution and use in source and binary forms, with or without
@@ -61,8 +61,8 @@
         /// </summary>
         public AuthInterceptorContext(string serviceUrl, string methodName)
         {
-            this.serviceUrl = Preconditions.CheckNotNull(serviceUrl);
-            this.methodName = Preconditions.CheckNotNull(methodName);
+            this.serviceUrl = GrpcPreconditions.CheckNotNull(serviceUrl);
+            this.methodName = GrpcPreconditions.CheckNotNull(methodName);
         }
 
         /// <summary>
diff --git a/src/csharp/Grpc.Core/CallCredentials.cs b/src/csharp/Grpc.Core/CallCredentials.cs
index a71c890..7cd41d0 100644
--- a/src/csharp/Grpc.Core/CallCredentials.cs
+++ b/src/csharp/Grpc.Core/CallCredentials.cs
@@ -1,6 +1,6 @@
 #region Copyright notice and license
 
-// Copyright 2015, Google Inc.
+// Copyright 2015-2016, Google Inc.
 // All rights reserved.
 //
 // Redistribution and use in source and binary forms, with or without
@@ -87,7 +87,7 @@
         /// <param name="interceptor">authentication interceptor</param>
         public MetadataCredentials(AsyncAuthInterceptor interceptor)
         {
-            this.interceptor = Preconditions.CheckNotNull(interceptor);
+            this.interceptor = GrpcPreconditions.CheckNotNull(interceptor);
         }
 
         internal override CallCredentialsSafeHandle ToNativeCredentials()
@@ -111,7 +111,7 @@
         /// <param name="credentials">credentials to compose</param>
         public CompositeCallCredentials(params CallCredentials[] credentials)
         {
-            Preconditions.CheckArgument(credentials.Length >= 2, "Composite credentials object can only be created from 2 or more credentials.");
+            GrpcPreconditions.CheckArgument(credentials.Length >= 2, "Composite credentials object can only be created from 2 or more credentials.");
             this.credentials = new List<CallCredentials>(credentials);
         }
 
diff --git a/src/csharp/Grpc.Core/CallInvocationDetails.cs b/src/csharp/Grpc.Core/CallInvocationDetails.cs
index 8228b8f..52bfbe6 100644
--- a/src/csharp/Grpc.Core/CallInvocationDetails.cs
+++ b/src/csharp/Grpc.Core/CallInvocationDetails.cs
@@ -1,6 +1,6 @@
 #region Copyright notice and license
 
-// Copyright 2015, Google Inc.
+// Copyright 2015-2016, Google Inc.
 // All rights reserved.
 //
 // Redistribution and use in source and binary forms, with or without
@@ -85,11 +85,11 @@
         /// <param name="options">Call options.</param>
         public CallInvocationDetails(Channel channel, string method, string host, Marshaller<TRequest> requestMarshaller, Marshaller<TResponse> responseMarshaller, CallOptions options)
         {
-            this.channel = Preconditions.CheckNotNull(channel, "channel");
-            this.method = Preconditions.CheckNotNull(method, "method");
+            this.channel = GrpcPreconditions.CheckNotNull(channel, "channel");
+            this.method = GrpcPreconditions.CheckNotNull(method, "method");
             this.host = host;
-            this.requestMarshaller = Preconditions.CheckNotNull(requestMarshaller, "requestMarshaller");
-            this.responseMarshaller = Preconditions.CheckNotNull(responseMarshaller, "responseMarshaller");
+            this.requestMarshaller = GrpcPreconditions.CheckNotNull(requestMarshaller, "requestMarshaller");
+            this.responseMarshaller = GrpcPreconditions.CheckNotNull(responseMarshaller, "responseMarshaller");
             this.options = options;
         }
 
diff --git a/src/csharp/Grpc.Core/CallOptions.cs b/src/csharp/Grpc.Core/CallOptions.cs
index 1fda80c..7bd95d4 100644
--- a/src/csharp/Grpc.Core/CallOptions.cs
+++ b/src/csharp/Grpc.Core/CallOptions.cs
@@ -1,6 +1,6 @@
 #region Copyright notice and license
 
-// Copyright 2015, Google Inc.
+// Copyright 2015-2016, Google Inc.
 // All rights reserved.
 //
 // Redistribution and use in source and binary forms, with or without
@@ -176,13 +176,13 @@
             {
                 if (propagationToken.Options.IsPropagateDeadline)
                 {
-                    Preconditions.CheckArgument(!newOptions.deadline.HasValue,
+                    GrpcPreconditions.CheckArgument(!newOptions.deadline.HasValue,
                         "Cannot propagate deadline from parent call. The deadline has already been set explicitly.");
                     newOptions.deadline = propagationToken.ParentDeadline;
                 }
                 if (propagationToken.Options.IsPropagateCancellation)
                 {
-                    Preconditions.CheckArgument(!newOptions.cancellationToken.CanBeCanceled,
+                    GrpcPreconditions.CheckArgument(!newOptions.cancellationToken.CanBeCanceled,
                         "Cannot propagate cancellation token from parent call. The cancellation token has already been set to a non-default value.");
                     newOptions.cancellationToken = propagationToken.ParentCancellationToken;
                 }
diff --git a/src/csharp/Grpc.Core/Channel.cs b/src/csharp/Grpc.Core/Channel.cs
index d8d43c7..d7a482d 100644
--- a/src/csharp/Grpc.Core/Channel.cs
+++ b/src/csharp/Grpc.Core/Channel.cs
@@ -1,5 +1,5 @@
 #region Copyright notice and license
-// Copyright 2015, Google Inc.
+// Copyright 2015-2016, Google Inc.
 // All rights reserved.
 //
 // Redistribution and use in source and binary forms, with or without
@@ -68,7 +68,7 @@
         /// <param name="options">Channel options.</param>
         public Channel(string target, ChannelCredentials credentials, IEnumerable<ChannelOption> options = null)
         {
-            this.target = Preconditions.CheckNotNull(target, "target");
+            this.target = GrpcPreconditions.CheckNotNull(target, "target");
             this.options = CreateOptionsDictionary(options);
             EnsureUserAgentChannelOption(this.options);
             this.environment = GrpcEnvironment.AddRef();
@@ -117,7 +117,7 @@
         /// </summary>
         public Task WaitForStateChangedAsync(ChannelState lastObservedState, DateTime? deadline = null)
         {
-            Preconditions.CheckArgument(lastObservedState != ChannelState.FatalFailure,
+            GrpcPreconditions.CheckArgument(lastObservedState != ChannelState.FatalFailure,
                 "FatalFailure is a terminal state. No further state changes can occur.");
             var tcs = new TaskCompletionSource<object>();
             var deadlineTimespec = deadline.HasValue ? Timespec.FromDateTime(deadline.Value) : Timespec.InfFuture;
@@ -184,7 +184,7 @@
         {
             lock (myLock)
             {
-                Preconditions.CheckState(!shutdownRequested);
+                GrpcPreconditions.CheckState(!shutdownRequested);
                 shutdownRequested = true;
             }
 
@@ -221,7 +221,7 @@
 
             bool success = false;
             handle.DangerousAddRef(ref success);
-            Preconditions.CheckState(success);
+            GrpcPreconditions.CheckState(success);
         }
 
         internal void RemoveCallReference(object call)
diff --git a/src/csharp/Grpc.Core/ChannelCredentials.cs b/src/csharp/Grpc.Core/ChannelCredentials.cs
index 5d96958..03cda28 100644
--- a/src/csharp/Grpc.Core/ChannelCredentials.cs
+++ b/src/csharp/Grpc.Core/ChannelCredentials.cs
@@ -1,6 +1,6 @@
 #region Copyright notice and license
 
-// Copyright 2015, Google Inc.
+// Copyright 2015-2016, Google Inc.
 // All rights reserved.
 //
 // Redistribution and use in source and binary forms, with or without
@@ -183,9 +183,9 @@
         /// <param name="callCredentials">channelCredentials to compose</param>
         public CompositeChannelCredentials(ChannelCredentials channelCredentials, CallCredentials callCredentials)
         {
-            this.channelCredentials = Preconditions.CheckNotNull(channelCredentials);
-            this.callCredentials = Preconditions.CheckNotNull(callCredentials);
-            Preconditions.CheckArgument(channelCredentials.IsComposable, "Supplied channel credentials do not allow composition.");
+            this.channelCredentials = GrpcPreconditions.CheckNotNull(channelCredentials);
+            this.callCredentials = GrpcPreconditions.CheckNotNull(callCredentials);
+            GrpcPreconditions.CheckArgument(channelCredentials.IsComposable, "Supplied channel credentials do not allow composition.");
         }
 
         internal override ChannelCredentialsSafeHandle ToNativeCredentials()
diff --git a/src/csharp/Grpc.Core/ChannelOptions.cs b/src/csharp/Grpc.Core/ChannelOptions.cs
index d70673c..65e15e2 100644
--- a/src/csharp/Grpc.Core/ChannelOptions.cs
+++ b/src/csharp/Grpc.Core/ChannelOptions.cs
@@ -1,5 +1,5 @@
 #region Copyright notice and license
-// Copyright 2015, Google Inc.
+// Copyright 2015-2016, Google Inc.
 // All rights reserved.
 //
 // Redistribution and use in source and binary forms, with or without
@@ -73,8 +73,8 @@
         public ChannelOption(string name, string stringValue)
         {
             this.type = OptionType.String;
-            this.name = Preconditions.CheckNotNull(name, "name");
-            this.stringValue = Preconditions.CheckNotNull(stringValue, "stringValue");
+            this.name = GrpcPreconditions.CheckNotNull(name, "name");
+            this.stringValue = GrpcPreconditions.CheckNotNull(stringValue, "stringValue");
         }
 
         /// <summary>
@@ -85,7 +85,7 @@
         public ChannelOption(string name, int intValue)
         {
             this.type = OptionType.Integer;
-            this.name = Preconditions.CheckNotNull(name, "name");
+            this.name = GrpcPreconditions.CheckNotNull(name, "name");
             this.intValue = intValue;
         }
 
@@ -118,7 +118,7 @@
         {
             get
             {
-                Preconditions.CheckState(type == OptionType.Integer);
+                GrpcPreconditions.CheckState(type == OptionType.Integer);
                 return intValue;
             }
         }
@@ -130,7 +130,7 @@
         {
             get
             {
-                Preconditions.CheckState(type == OptionType.String);
+                GrpcPreconditions.CheckState(type == OptionType.String);
                 return stringValue;
             }
         }
diff --git a/src/csharp/Grpc.Core/ContextPropagationToken.cs b/src/csharp/Grpc.Core/ContextPropagationToken.cs
index 1d899b9..c0f638f 100644
--- a/src/csharp/Grpc.Core/ContextPropagationToken.cs
+++ b/src/csharp/Grpc.Core/ContextPropagationToken.cs
@@ -1,6 +1,6 @@
 #region Copyright notice and license
 
-// Copyright 2015, Google Inc.
+// Copyright 2015-2016, Google Inc.
 // All rights reserved.
 //
 // Redistribution and use in source and binary forms, with or without
@@ -68,7 +68,7 @@
 
         internal ContextPropagationToken(CallSafeHandle parentCall, DateTime deadline, CancellationToken cancellationToken, ContextPropagationOptions options)
         {
-            this.parentCall = Preconditions.CheckNotNull(parentCall);
+            this.parentCall = GrpcPreconditions.CheckNotNull(parentCall);
             this.deadline = deadline;
             this.cancellationToken = cancellationToken;
             this.options = options ?? ContextPropagationOptions.Default;
diff --git a/src/csharp/Grpc.Core/Grpc.Core.csproj b/src/csharp/Grpc.Core/Grpc.Core.csproj
index 8d7d2ca..3189835 100644
--- a/src/csharp/Grpc.Core/Grpc.Core.csproj
+++ b/src/csharp/Grpc.Core/Grpc.Core.csproj
@@ -39,8 +39,7 @@
   </PropertyGroup>
   <ItemGroup>
     <Reference Include="System" />
-    <Reference Include="System.Interactive.Async, Version=1.2.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
-      <SpecificVersion>False</SpecificVersion>
+    <Reference Include="System.Interactive.Async">
       <HintPath>..\packages\Ix-Async.1.2.5\lib\net45\System.Interactive.Async.dll</HintPath>
     </Reference>
   </ItemGroup>
@@ -91,7 +90,6 @@
     <Compile Include="Internal\AsyncCallBase.cs" />
     <Compile Include="Internal\AsyncCallServer.cs" />
     <Compile Include="Internal\AsyncCall.cs" />
-    <Compile Include="Utils\Preconditions.cs" />
     <Compile Include="Internal\ServerCredentialsSafeHandle.cs" />
     <Compile Include="ServerCredentials.cs" />
     <Compile Include="Metadata.cs" />
@@ -130,6 +128,7 @@
     <Compile Include="Profiling\IProfiler.cs" />
     <Compile Include="Profiling\Profilers.cs" />
     <Compile Include="Internal\DefaultSslRootsOverride.cs" />
+    <Compile Include="Utils\GrpcPreconditions.cs" />
   </ItemGroup>
   <ItemGroup>
     <None Include="Grpc.Core.nuspec" />
diff --git a/src/csharp/Grpc.Core/GrpcEnvironment.cs b/src/csharp/Grpc.Core/GrpcEnvironment.cs
index f3aa3d7..86b37b8 100644
--- a/src/csharp/Grpc.Core/GrpcEnvironment.cs
+++ b/src/csharp/Grpc.Core/GrpcEnvironment.cs
@@ -83,7 +83,7 @@
         {
             lock (staticLock)
             {
-                Preconditions.CheckState(refCount > 0);
+                GrpcPreconditions.CheckState(refCount > 0);
                 refCount--;
                 if (refCount == 0)
                 {
@@ -118,7 +118,7 @@
         /// </summary>
         public static void SetLogger(ILogger customLogger)
         {
-            Preconditions.CheckNotNull(customLogger, "customLogger");
+            GrpcPreconditions.CheckNotNull(customLogger, "customLogger");
             logger = customLogger;
         }
 
diff --git a/src/csharp/Grpc.Core/Internal/AsyncCall.cs b/src/csharp/Grpc.Core/Internal/AsyncCall.cs
index 7dc4490..2caba26 100644
--- a/src/csharp/Grpc.Core/Internal/AsyncCall.cs
+++ b/src/csharp/Grpc.Core/Internal/AsyncCall.cs
@@ -99,7 +99,7 @@
 
                 lock (myLock)
                 {
-                    Preconditions.CheckState(!started);
+                    GrpcPreconditions.CheckState(!started);
                     started = true;
                     Initialize(cq);
 
@@ -141,7 +141,7 @@
         {
             lock (myLock)
             {
-                Preconditions.CheckState(!started);
+                GrpcPreconditions.CheckState(!started);
                 started = true;
 
                 Initialize(environment.CompletionQueue);
@@ -168,7 +168,7 @@
         {
             lock (myLock)
             {
-                Preconditions.CheckState(!started);
+                GrpcPreconditions.CheckState(!started);
                 started = true;
 
                 Initialize(environment.CompletionQueue);
@@ -192,7 +192,7 @@
         {
             lock (myLock)
             {
-                Preconditions.CheckState(!started);
+                GrpcPreconditions.CheckState(!started);
                 started = true;
 
                 Initialize(environment.CompletionQueue);
@@ -217,7 +217,7 @@
         {
             lock (myLock)
             {
-                Preconditions.CheckState(!started);
+                GrpcPreconditions.CheckState(!started);
                 started = true;
 
                 Initialize(environment.CompletionQueue);
@@ -257,7 +257,7 @@
         {
             lock (myLock)
             {
-                Preconditions.CheckNotNull(completionDelegate, "Completion delegate cannot be null");
+                GrpcPreconditions.CheckNotNull(completionDelegate, "Completion delegate cannot be null");
                 CheckSendingAllowed();
 
                 call.StartSendCloseFromClient(HandleHalfclosed);
@@ -297,7 +297,7 @@
         {
             lock (myLock)
             {
-                Preconditions.CheckState(finishedStatus.HasValue, "Status can only be accessed once the call has finished.");
+                GrpcPreconditions.CheckState(finishedStatus.HasValue, "Status can only be accessed once the call has finished.");
                 return finishedStatus.Value.Status;
             }
         }
@@ -310,7 +310,7 @@
         {
             lock (myLock)
             {
-                Preconditions.CheckState(finishedStatus.HasValue, "Trailers can only be accessed once the call has finished.");
+                GrpcPreconditions.CheckState(finishedStatus.HasValue, "Trailers can only be accessed once the call has finished.");
                 return finishedStatus.Value.Trailers;
             }
         }
diff --git a/src/csharp/Grpc.Core/Internal/AsyncCallBase.cs b/src/csharp/Grpc.Core/Internal/AsyncCallBase.cs
index 81a9a40..45d4c3e 100644
--- a/src/csharp/Grpc.Core/Internal/AsyncCallBase.cs
+++ b/src/csharp/Grpc.Core/Internal/AsyncCallBase.cs
@@ -79,9 +79,9 @@
 
         public AsyncCallBase(Func<TWrite, byte[]> serializer, Func<byte[], TRead> deserializer, GrpcEnvironment environment)
         {
-            this.serializer = Preconditions.CheckNotNull(serializer);
-            this.deserializer = Preconditions.CheckNotNull(deserializer);
-            this.environment = Preconditions.CheckNotNull(environment);
+            this.serializer = GrpcPreconditions.CheckNotNull(serializer);
+            this.deserializer = GrpcPreconditions.CheckNotNull(deserializer);
+            this.environment = GrpcPreconditions.CheckNotNull(environment);
         }
 
         /// <summary>
@@ -91,7 +91,7 @@
         {
             lock (myLock)
             {
-                Preconditions.CheckState(started);
+                GrpcPreconditions.CheckState(started);
                 cancelRequested = true;
 
                 if (!disposed)
@@ -135,7 +135,7 @@
 
             lock (myLock)
             {
-                Preconditions.CheckNotNull(completionDelegate, "Completion delegate cannot be null");
+                GrpcPreconditions.CheckNotNull(completionDelegate, "Completion delegate cannot be null");
                 CheckSendingAllowed();
 
                 call.StartSendMessage(HandleSendFinished, payload, writeFlags, !initialMetadataSent);
@@ -154,7 +154,7 @@
         {
             lock (myLock)
             {
-                Preconditions.CheckNotNull(completionDelegate, "Completion delegate cannot be null");
+                GrpcPreconditions.CheckNotNull(completionDelegate, "Completion delegate cannot be null");
                 CheckReadingAllowed();
 
                 call.StartReceiveMessage(HandleReadFinished);
@@ -204,22 +204,22 @@
 
         protected void CheckSendingAllowed()
         {
-            Preconditions.CheckState(started);
+            GrpcPreconditions.CheckState(started);
             CheckNotCancelled();
-            Preconditions.CheckState(!disposed);
+            GrpcPreconditions.CheckState(!disposed);
 
-            Preconditions.CheckState(!halfcloseRequested, "Already halfclosed.");
-            Preconditions.CheckState(!finished, "Already finished.");
-            Preconditions.CheckState(sendCompletionDelegate == null, "Only one write can be pending at a time");
+            GrpcPreconditions.CheckState(!halfcloseRequested, "Already halfclosed.");
+            GrpcPreconditions.CheckState(!finished, "Already finished.");
+            GrpcPreconditions.CheckState(sendCompletionDelegate == null, "Only one write can be pending at a time");
         }
 
         protected virtual void CheckReadingAllowed()
         {
-            Preconditions.CheckState(started);
-            Preconditions.CheckState(!disposed);
+            GrpcPreconditions.CheckState(started);
+            GrpcPreconditions.CheckState(!disposed);
 
-            Preconditions.CheckState(!readingDone, "Stream has already been closed.");
-            Preconditions.CheckState(readCompletionDelegate == null, "Only one read can be pending at a time");
+            GrpcPreconditions.CheckState(!readingDone, "Stream has already been closed.");
+            GrpcPreconditions.CheckState(readCompletionDelegate == null, "Only one read can be pending at a time");
         }
 
         protected void CheckNotCancelled()
diff --git a/src/csharp/Grpc.Core/Internal/AsyncCallServer.cs b/src/csharp/Grpc.Core/Internal/AsyncCallServer.cs
index 6752d3f..9380c0d 100644
--- a/src/csharp/Grpc.Core/Internal/AsyncCallServer.cs
+++ b/src/csharp/Grpc.Core/Internal/AsyncCallServer.cs
@@ -53,7 +53,7 @@
 
         public AsyncCallServer(Func<TResponse, byte[]> serializer, Func<byte[], TRequest> deserializer, GrpcEnvironment environment, Server server) : base(serializer, deserializer, environment)
         {
-            this.server = Preconditions.CheckNotNull(server);
+            this.server = GrpcPreconditions.CheckNotNull(server);
         }
 
         public void Initialize(CallSafeHandle call)
@@ -71,7 +71,7 @@
         {
             lock (myLock)
             {
-                Preconditions.CheckNotNull(call);
+                GrpcPreconditions.CheckNotNull(call);
 
                 started = true;
 
@@ -108,14 +108,14 @@
         {
             lock (myLock)
             {
-                Preconditions.CheckNotNull(headers, "metadata");
-                Preconditions.CheckNotNull(completionDelegate, "Completion delegate cannot be null");
+                GrpcPreconditions.CheckNotNull(headers, "metadata");
+                GrpcPreconditions.CheckNotNull(completionDelegate, "Completion delegate cannot be null");
 
-                Preconditions.CheckState(!initialMetadataSent, "Response headers can only be sent once per call.");
-                Preconditions.CheckState(streamingWritesCounter == 0, "Response headers can only be sent before the first write starts.");
+                GrpcPreconditions.CheckState(!initialMetadataSent, "Response headers can only be sent once per call.");
+                GrpcPreconditions.CheckState(streamingWritesCounter == 0, "Response headers can only be sent before the first write starts.");
                 CheckSendingAllowed();
 
-                Preconditions.CheckNotNull(completionDelegate, "Completion delegate cannot be null");
+                GrpcPreconditions.CheckNotNull(completionDelegate, "Completion delegate cannot be null");
 
                 using (var metadataArray = MetadataArraySafeHandle.Create(headers))
                 {
@@ -136,7 +136,7 @@
         {
             lock (myLock)
             {
-                Preconditions.CheckNotNull(completionDelegate, "Completion delegate cannot be null");
+                GrpcPreconditions.CheckNotNull(completionDelegate, "Completion delegate cannot be null");
                 CheckSendingAllowed();
 
                 using (var metadataArray = MetadataArraySafeHandle.Create(trailers))
@@ -177,7 +177,7 @@
         protected override void CheckReadingAllowed()
         {
             base.CheckReadingAllowed();
-            Preconditions.CheckArgument(!cancelRequested);
+            GrpcPreconditions.CheckArgument(!cancelRequested);
         }
 
         protected override void OnAfterReleaseResources()
@@ -193,16 +193,6 @@
             lock (myLock)
             {
                 finished = true;
-
-                if (cancelled)
-                {
-                    // Once we cancel, we don't have to care that much 
-                    // about reads and writes.
-
-                    // TODO(jtattermusch): is this still necessary?
-                    Cancel();
-                }
-
                 ReleaseResourcesIfPossible();
             }
             // TODO(jtattermusch): handle error
diff --git a/src/csharp/Grpc.Core/Internal/CompletionQueueSafeHandle.cs b/src/csharp/Grpc.Core/Internal/CompletionQueueSafeHandle.cs
index 9d7a990..5c75b52 100644
--- a/src/csharp/Grpc.Core/Internal/CompletionQueueSafeHandle.cs
+++ b/src/csharp/Grpc.Core/Internal/CompletionQueueSafeHandle.cs
@@ -101,7 +101,7 @@
         {
             bool success = false;
             shutdownRefcount.IncrementIfNonzero(ref success);
-            Preconditions.CheckState(success, "Shutdown has already been called");
+            GrpcPreconditions.CheckState(success, "Shutdown has already been called");
         }
 
         private void EndOp()
diff --git a/src/csharp/Grpc.Core/Internal/CompletionRegistry.cs b/src/csharp/Grpc.Core/Internal/CompletionRegistry.cs
index 2796c95..3a293e1 100644
--- a/src/csharp/Grpc.Core/Internal/CompletionRegistry.cs
+++ b/src/csharp/Grpc.Core/Internal/CompletionRegistry.cs
@@ -1,6 +1,6 @@
 #region Copyright notice and license
 
-// Copyright 2015, Google Inc.
+// Copyright 2015-2016, Google Inc.
 // All rights reserved.
 //
 // Redistribution and use in source and binary forms, with or without
@@ -59,7 +59,7 @@
         public void Register(IntPtr key, OpCompletionDelegate callback)
         {
             environment.DebugStats.PendingBatchCompletions.Increment();
-            Preconditions.CheckState(dict.TryAdd(key, callback));
+            GrpcPreconditions.CheckState(dict.TryAdd(key, callback));
         }
 
         public void RegisterBatchCompletion(BatchContextSafeHandle ctx, BatchCompletionDelegate callback)
@@ -71,7 +71,7 @@
         public OpCompletionDelegate Extract(IntPtr key)
         {
             OpCompletionDelegate value;
-            Preconditions.CheckState(dict.TryRemove(key, out value));
+            GrpcPreconditions.CheckState(dict.TryRemove(key, out value));
             environment.DebugStats.PendingBatchCompletions.Decrement();
             return value;
         }
diff --git a/src/csharp/Grpc.Core/Internal/DefaultSslRootsOverride.cs b/src/csharp/Grpc.Core/Internal/DefaultSslRootsOverride.cs
index eeaa7ad..dfaee5d 100644
--- a/src/csharp/Grpc.Core/Internal/DefaultSslRootsOverride.cs
+++ b/src/csharp/Grpc.Core/Internal/DefaultSslRootsOverride.cs
@@ -56,7 +56,7 @@
         {
             lock (staticLock)
             {
-                var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(RootsPemResourceName);
+                var stream = typeof(DefaultSslRootsOverride).GetTypeInfo().Assembly.GetManifestResourceStream(RootsPemResourceName);
                 if (stream == null)
                 {
                     throw new IOException(string.Format("Error loading the embedded resource \"{0}\"", RootsPemResourceName));   
diff --git a/src/csharp/Grpc.Core/Internal/Enums.cs b/src/csharp/Grpc.Core/Internal/Enums.cs
index b0eab20..098e7c0 100644
--- a/src/csharp/Grpc.Core/Internal/Enums.cs
+++ b/src/csharp/Grpc.Core/Internal/Enums.cs
@@ -1,6 +1,6 @@
 #region Copyright notice and license
 
-// Copyright 2015, Google Inc.
+// Copyright 2015-2016, Google Inc.
 // All rights reserved.
 //
 // Redistribution and use in source and binary forms, with or without
@@ -72,7 +72,7 @@
         /// </summary>
         public static void CheckOk(this GRPCCallError callError)
         {
-            Preconditions.CheckState(callError == GRPCCallError.OK, "Call error: " + callError);
+            GrpcPreconditions.CheckState(callError == GRPCCallError.OK, "Call error: " + callError);
         }
     }
 
diff --git a/src/csharp/Grpc.Core/Internal/NativeMetadataCredentialsPlugin.cs b/src/csharp/Grpc.Core/Internal/NativeMetadataCredentialsPlugin.cs
index 36b865c..e810ffc 100644
--- a/src/csharp/Grpc.Core/Internal/NativeMetadataCredentialsPlugin.cs
+++ b/src/csharp/Grpc.Core/Internal/NativeMetadataCredentialsPlugin.cs
@@ -53,7 +53,7 @@
 
         public NativeMetadataCredentialsPlugin(AsyncAuthInterceptor interceptor)
         {
-            this.interceptor = Preconditions.CheckNotNull(interceptor, "interceptor");
+            this.interceptor = GrpcPreconditions.CheckNotNull(interceptor, "interceptor");
             this.nativeInterceptor = NativeMetadataInterceptorHandler;
 
             // Make sure the callback doesn't get garbage collected until it is destroyed.
diff --git a/src/csharp/Grpc.Core/Internal/PlatformApis.cs b/src/csharp/Grpc.Core/Internal/PlatformApis.cs
index f0c5b0f..fb1acfb 100644
--- a/src/csharp/Grpc.Core/Internal/PlatformApis.cs
+++ b/src/csharp/Grpc.Core/Internal/PlatformApis.cs
@@ -53,12 +53,18 @@
 
         static PlatformApis()
         {
+#if DNXCORE50
+            isLinux = RuntimeInformation.IsOSPlatform(OSPlatform.Linux);
+            isMacOSX = RuntimeInformation.IsOSPlatform(OSPlatform.OSX);
+            isWindows = RuntimeInformation.IsOSPlatform(OSPlatform.Windows);
+#else
             var platform = Environment.OSVersion.Platform;
 
             // PlatformID.MacOSX is never returned, commonly used trick is to identify Mac is by using uname.
             isMacOSX = (platform == PlatformID.Unix && GetUname() == "Darwin");
             isLinux = (platform == PlatformID.Unix && !isMacOSX);
             isWindows = (platform == PlatformID.Win32NT || platform == PlatformID.Win32S || platform == PlatformID.Win32Windows);
+#endif
             isMono = Type.GetType("Mono.Runtime") != null;
         }
 
diff --git a/src/csharp/Grpc.Core/Internal/ServerCallHandler.cs b/src/csharp/Grpc.Core/Internal/ServerCallHandler.cs
index de66759..ccf144d 100644
--- a/src/csharp/Grpc.Core/Internal/ServerCallHandler.cs
+++ b/src/csharp/Grpc.Core/Internal/ServerCallHandler.cs
@@ -1,6 +1,6 @@
 #region Copyright notice and license
 
-// Copyright 2015, Google Inc.
+// Copyright 2015-2016, Google Inc.
 // All rights reserved.
 //
 // Redistribution and use in source and binary forms, with or without
@@ -78,10 +78,10 @@
             var context = HandlerUtils.NewContext(newRpc, asyncCall.Peer, responseStream, asyncCall.CancellationToken);
             try
             {
-                Preconditions.CheckArgument(await requestStream.MoveNext().ConfigureAwait(false));
+                GrpcPreconditions.CheckArgument(await requestStream.MoveNext().ConfigureAwait(false));
                 var request = requestStream.Current;
                 // TODO(jtattermusch): we need to read the full stream so that native callhandle gets deallocated.
-                Preconditions.CheckArgument(!await requestStream.MoveNext().ConfigureAwait(false));
+                GrpcPreconditions.CheckArgument(!await requestStream.MoveNext().ConfigureAwait(false));
                 var result = await handler(request, context).ConfigureAwait(false);
                 status = context.Status;
                 await responseStream.WriteAsync(result).ConfigureAwait(false);
@@ -134,10 +134,10 @@
             var context = HandlerUtils.NewContext(newRpc, asyncCall.Peer, responseStream, asyncCall.CancellationToken);
             try
             {
-                Preconditions.CheckArgument(await requestStream.MoveNext().ConfigureAwait(false));
+                GrpcPreconditions.CheckArgument(await requestStream.MoveNext().ConfigureAwait(false));
                 var request = requestStream.Current;
                 // TODO(jtattermusch): we need to read the full stream so that native callhandle gets deallocated.
-                Preconditions.CheckArgument(!await requestStream.MoveNext().ConfigureAwait(false));
+                GrpcPreconditions.CheckArgument(!await requestStream.MoveNext().ConfigureAwait(false));
                 await handler(request, responseStream, context).ConfigureAwait(false);
                 status = context.Status;
             }
diff --git a/src/csharp/Grpc.Core/Internal/ServerCredentialsSafeHandle.cs b/src/csharp/Grpc.Core/Internal/ServerCredentialsSafeHandle.cs
index a1d080c..a50f357 100644
--- a/src/csharp/Grpc.Core/Internal/ServerCredentialsSafeHandle.cs
+++ b/src/csharp/Grpc.Core/Internal/ServerCredentialsSafeHandle.cs
@@ -49,7 +49,7 @@
 
         public static ServerCredentialsSafeHandle CreateSslCredentials(string pemRootCerts, string[] keyCertPairCertChainArray, string[] keyCertPairPrivateKeyArray, bool forceClientAuth)
         {
-            Preconditions.CheckArgument(keyCertPairCertChainArray.Length == keyCertPairPrivateKeyArray.Length);
+            GrpcPreconditions.CheckArgument(keyCertPairCertChainArray.Length == keyCertPairPrivateKeyArray.Length);
             return Native.grpcsharp_ssl_server_credentials_create(pemRootCerts,
                                                                   keyCertPairCertChainArray, keyCertPairPrivateKeyArray,
                                                                   new UIntPtr((ulong)keyCertPairCertChainArray.Length),
diff --git a/src/csharp/Grpc.Core/Internal/Timespec.cs b/src/csharp/Grpc.Core/Internal/Timespec.cs
index 148d877..754be4e 100644
--- a/src/csharp/Grpc.Core/Internal/Timespec.cs
+++ b/src/csharp/Grpc.Core/Internal/Timespec.cs
@@ -141,8 +141,8 @@
         /// </summary>
         public DateTime ToDateTime()
         {
-            Preconditions.CheckState(tv_nsec >= 0 && tv_nsec < NanosPerSecond);
-            Preconditions.CheckState(clock_type == GPRClockType.Realtime);
+            GrpcPreconditions.CheckState(tv_nsec >= 0 && tv_nsec < NanosPerSecond);
+            GrpcPreconditions.CheckState(clock_type == GPRClockType.Realtime);
 
             // fast path for InfFuture
             if (this.Equals(InfFuture))
@@ -195,7 +195,7 @@
                 return Timespec.InfPast;
             }
 
-            Preconditions.CheckArgument(dateTime.Kind == DateTimeKind.Utc, "dateTime needs of kind DateTimeKind.Utc or be equal to DateTime.MaxValue or DateTime.MinValue.");
+            GrpcPreconditions.CheckArgument(dateTime.Kind == DateTimeKind.Utc, "dateTime needs of kind DateTimeKind.Utc or be equal to DateTime.MaxValue or DateTime.MinValue.");
 
             try
             {
diff --git a/src/csharp/Grpc.Core/Internal/UnmanagedLibrary.cs b/src/csharp/Grpc.Core/Internal/UnmanagedLibrary.cs
index 95a8797..e763c15 100644
--- a/src/csharp/Grpc.Core/Internal/UnmanagedLibrary.cs
+++ b/src/csharp/Grpc.Core/Internal/UnmanagedLibrary.cs
@@ -65,7 +65,7 @@
 
         public UnmanagedLibrary(string libraryPath)
         {
-            this.libraryPath = Preconditions.CheckNotNull(libraryPath);
+            this.libraryPath = GrpcPreconditions.CheckNotNull(libraryPath);
 
             if (!File.Exists(this.libraryPath))
             {
diff --git a/src/csharp/Grpc.Core/KeyCertificatePair.cs b/src/csharp/Grpc.Core/KeyCertificatePair.cs
index 6f69197..0fb6817 100644
--- a/src/csharp/Grpc.Core/KeyCertificatePair.cs
+++ b/src/csharp/Grpc.Core/KeyCertificatePair.cs
@@ -1,6 +1,6 @@
 #region Copyright notice and license
 
-// Copyright 2015, Google Inc.
+// Copyright 2015-2016, Google Inc.
 // All rights reserved.
 //
 // Redistribution and use in source and binary forms, with or without
@@ -54,8 +54,8 @@
         /// <param name="privateKey">PEM encoded private key.</param>
         public KeyCertificatePair(string certificateChain, string privateKey)
         {
-            this.certificateChain = Preconditions.CheckNotNull(certificateChain, "certificateChain");
-            this.privateKey = Preconditions.CheckNotNull(privateKey, "privateKey");
+            this.certificateChain = GrpcPreconditions.CheckNotNull(certificateChain, "certificateChain");
+            this.privateKey = GrpcPreconditions.CheckNotNull(privateKey, "privateKey");
         }
 
         /// <summary>
diff --git a/src/csharp/Grpc.Core/Marshaller.cs b/src/csharp/Grpc.Core/Marshaller.cs
index 3493d2d..5847248 100644
--- a/src/csharp/Grpc.Core/Marshaller.cs
+++ b/src/csharp/Grpc.Core/Marshaller.cs
@@ -1,6 +1,6 @@
 #region Copyright notice and license
 
-// Copyright 2015, Google Inc.
+// Copyright 2015-2016, Google Inc.
 // All rights reserved.
 //
 // Redistribution and use in source and binary forms, with or without
@@ -51,8 +51,8 @@
         /// <param name="deserializer">Function that will be used to deserialize messages.</param>
         public Marshaller(Func<T, byte[]> serializer, Func<byte[], T> deserializer)
         {
-            this.serializer = Preconditions.CheckNotNull(serializer, "serializer");
-            this.deserializer = Preconditions.CheckNotNull(deserializer, "deserializer");
+            this.serializer = GrpcPreconditions.CheckNotNull(serializer, "serializer");
+            this.deserializer = GrpcPreconditions.CheckNotNull(deserializer, "deserializer");
         }
 
         /// <summary>
diff --git a/src/csharp/Grpc.Core/Metadata.cs b/src/csharp/Grpc.Core/Metadata.cs
index 21bdf4f..aa22f84 100644
--- a/src/csharp/Grpc.Core/Metadata.cs
+++ b/src/csharp/Grpc.Core/Metadata.cs
@@ -1,5 +1,5 @@
 #region Copyright notice and license
-// Copyright 2015, Google Inc.
+// Copyright 2015-2016, Google Inc.
 // All rights reserved.
 //
 // Redistribution and use in source and binary forms, with or without
@@ -179,7 +179,7 @@
 
         private void CheckWriteable()
         {
-            Preconditions.CheckState(!readOnly, "Object is read only");
+            GrpcPreconditions.CheckState(!readOnly, "Object is read only");
         }
 
         #endregion
@@ -211,10 +211,10 @@
             public Entry(string key, byte[] valueBytes)
             {
                 this.key = NormalizeKey(key);
-                Preconditions.CheckArgument(this.key.EndsWith(BinaryHeaderSuffix),
+                GrpcPreconditions.CheckArgument(this.key.EndsWith(BinaryHeaderSuffix),
                     "Key for binary valued metadata entry needs to have suffix indicating binary value.");
                 this.value = null;
-                Preconditions.CheckNotNull(valueBytes, "valueBytes");
+                GrpcPreconditions.CheckNotNull(valueBytes, "valueBytes");
                 this.valueBytes = new byte[valueBytes.Length];
                 Buffer.BlockCopy(valueBytes, 0, this.valueBytes, 0, valueBytes.Length);  // defensive copy to guarantee immutability
             }
@@ -227,9 +227,9 @@
             public Entry(string key, string value)
             {
                 this.key = NormalizeKey(key);
-                Preconditions.CheckArgument(!this.key.EndsWith(BinaryHeaderSuffix),
+                GrpcPreconditions.CheckArgument(!this.key.EndsWith(BinaryHeaderSuffix),
                     "Key for ASCII valued metadata entry cannot have suffix indicating binary value.");
-                this.value = Preconditions.CheckNotNull(value, "value");
+                this.value = GrpcPreconditions.CheckNotNull(value, "value");
                 this.valueBytes = null;
             }
 
@@ -270,7 +270,7 @@
             {
                 get
                 {
-                    Preconditions.CheckState(!IsBinary, "Cannot access string value of a binary metadata entry");
+                    GrpcPreconditions.CheckState(!IsBinary, "Cannot access string value of a binary metadata entry");
                     return value ?? Encoding.GetString(valueBytes);
                 }
             }
@@ -323,8 +323,8 @@
 
             private static string NormalizeKey(string key)
             {
-                var normalized = Preconditions.CheckNotNull(key, "key").ToLower(CultureInfo.InvariantCulture);
-                Preconditions.CheckArgument(ValidKeyRegex.IsMatch(normalized), 
+                var normalized = GrpcPreconditions.CheckNotNull(key, "key").ToLower(CultureInfo.InvariantCulture);
+                GrpcPreconditions.CheckArgument(ValidKeyRegex.IsMatch(normalized), 
                     "Metadata entry key not valid. Keys can only contain lowercase alphanumeric characters, underscores and hyphens.");
                 return normalized;
             }
diff --git a/src/csharp/Grpc.Core/Method.cs b/src/csharp/Grpc.Core/Method.cs
index 99162a7..3870076 100644
--- a/src/csharp/Grpc.Core/Method.cs
+++ b/src/csharp/Grpc.Core/Method.cs
@@ -1,6 +1,6 @@
 #region Copyright notice and license
 
-// Copyright 2015, Google Inc.
+// Copyright 2015-2016, Google Inc.
 // All rights reserved.
 //
 // Redistribution and use in source and binary forms, with or without
@@ -106,10 +106,10 @@
         public Method(MethodType type, string serviceName, string name, Marshaller<TRequest> requestMarshaller, Marshaller<TResponse> responseMarshaller)
         {
             this.type = type;
-            this.serviceName = Preconditions.CheckNotNull(serviceName, "serviceName");
-            this.name = Preconditions.CheckNotNull(name, "name");
-            this.requestMarshaller = Preconditions.CheckNotNull(requestMarshaller, "requestMarshaller");
-            this.responseMarshaller = Preconditions.CheckNotNull(responseMarshaller, "responseMarshaller");
+            this.serviceName = GrpcPreconditions.CheckNotNull(serviceName, "serviceName");
+            this.name = GrpcPreconditions.CheckNotNull(name, "name");
+            this.requestMarshaller = GrpcPreconditions.CheckNotNull(requestMarshaller, "requestMarshaller");
+            this.responseMarshaller = GrpcPreconditions.CheckNotNull(responseMarshaller, "responseMarshaller");
             this.fullName = GetFullName(serviceName, name);
         }
 
diff --git a/src/csharp/Grpc.Core/Server.cs b/src/csharp/Grpc.Core/Server.cs
index d120f95..5d0fc6b 100644
--- a/src/csharp/Grpc.Core/Server.cs
+++ b/src/csharp/Grpc.Core/Server.cs
@@ -1,6 +1,6 @@
 #region Copyright notice and license
 
-// Copyright 2015, Google Inc.
+// Copyright 2015-2016, Google Inc.
 // All rights reserved.
 //
 // Redistribution and use in source and binary forms, with or without
@@ -125,7 +125,7 @@
         {
             lock (myLock)
             {
-                Preconditions.CheckState(!startRequested);
+                GrpcPreconditions.CheckState(!startRequested);
                 startRequested = true;
                 
                 handle.Start();
@@ -142,8 +142,8 @@
         {
             lock (myLock)
             {
-                Preconditions.CheckState(startRequested);
-                Preconditions.CheckState(!shutdownRequested);
+                GrpcPreconditions.CheckState(startRequested);
+                GrpcPreconditions.CheckState(!shutdownRequested);
                 shutdownRequested = true;
             }
 
@@ -162,8 +162,8 @@
         {
             lock (myLock)
             {
-                Preconditions.CheckState(startRequested);
-                Preconditions.CheckState(!shutdownRequested);
+                GrpcPreconditions.CheckState(startRequested);
+                GrpcPreconditions.CheckState(!shutdownRequested);
                 shutdownRequested = true;
             }
 
@@ -181,7 +181,7 @@
 
             bool success = false;
             handle.DangerousAddRef(ref success);
-            Preconditions.CheckState(success);
+            GrpcPreconditions.CheckState(success);
         }
 
         internal void RemoveCallReference(object call)
@@ -197,7 +197,7 @@
         {
             lock (myLock)
             {
-                Preconditions.CheckState(!startRequested);
+                GrpcPreconditions.CheckState(!startRequested);
                 foreach (var entry in serviceDefinition.CallHandlers)
                 {
                     callHandlers.Add(entry.Key, entry.Value);
@@ -213,8 +213,8 @@
         {
             lock (myLock)
             {
-                Preconditions.CheckNotNull(serverPort.Credentials, "serverPort");
-                Preconditions.CheckState(!startRequested);
+                GrpcPreconditions.CheckNotNull(serverPort.Credentials, "serverPort");
+                GrpcPreconditions.CheckState(!startRequested);
                 var address = string.Format("{0}:{1}", serverPort.Host, serverPort.Port);
                 int boundPort;
                 using (var nativeCredentials = serverPort.Credentials.ToNativeCredentials())
diff --git a/src/csharp/Grpc.Core/ServerCredentials.cs b/src/csharp/Grpc.Core/ServerCredentials.cs
index 3c6703d..456d331 100644
--- a/src/csharp/Grpc.Core/ServerCredentials.cs
+++ b/src/csharp/Grpc.Core/ServerCredentials.cs
@@ -1,6 +1,6 @@
 #region Copyright notice and license
 
-// Copyright 2015, Google Inc.
+// Copyright 2015-2016, Google Inc.
 // All rights reserved.
 //
 // Redistribution and use in source and binary forms, with or without
@@ -90,11 +90,11 @@
         public SslServerCredentials(IEnumerable<KeyCertificatePair> keyCertificatePairs, string rootCertificates, bool forceClientAuth)
         {
             this.keyCertificatePairs = new List<KeyCertificatePair>(keyCertificatePairs).AsReadOnly();
-            Preconditions.CheckArgument(this.keyCertificatePairs.Count > 0,
+            GrpcPreconditions.CheckArgument(this.keyCertificatePairs.Count > 0,
                 "At least one KeyCertificatePair needs to be provided.");
             if (forceClientAuth)
             {
-                Preconditions.CheckNotNull(rootCertificates,
+                GrpcPreconditions.CheckNotNull(rootCertificates,
                     "Cannot force client authentication unless you provide rootCertificates.");
             }
             this.rootCertificates = rootCertificates;
diff --git a/src/csharp/Grpc.Core/ServerPort.cs b/src/csharp/Grpc.Core/ServerPort.cs
index 598404d..10ddcb7 100644
--- a/src/csharp/Grpc.Core/ServerPort.cs
+++ b/src/csharp/Grpc.Core/ServerPort.cs
@@ -1,6 +1,6 @@
 #region Copyright notice and license
 
-// Copyright 2015, Google Inc.
+// Copyright 2015-2016, Google Inc.
 // All rights reserved.
 //
 // Redistribution and use in source and binary forms, with or without
@@ -62,9 +62,9 @@
         /// <param name="credentials">credentials to use to secure this port.</param>
         public ServerPort(string host, int port, ServerCredentials credentials)
         {
-            this.host = Preconditions.CheckNotNull(host, "host");
+            this.host = GrpcPreconditions.CheckNotNull(host, "host");
             this.port = port;
-            this.credentials = Preconditions.CheckNotNull(credentials, "credentials");
+            this.credentials = GrpcPreconditions.CheckNotNull(credentials, "credentials");
         }
 
         /// <summary>
diff --git a/src/csharp/Grpc.Core/Utils/Preconditions.cs b/src/csharp/Grpc.Core/Utils/GrpcPreconditions.cs
similarity index 98%
rename from src/csharp/Grpc.Core/Utils/Preconditions.cs
rename to src/csharp/Grpc.Core/Utils/GrpcPreconditions.cs
index a8ab603..76bf04c 100644
--- a/src/csharp/Grpc.Core/Utils/Preconditions.cs
+++ b/src/csharp/Grpc.Core/Utils/GrpcPreconditions.cs
@@ -1,6 +1,6 @@
 #region Copyright notice and license
 
-// Copyright 2015, Google Inc.
+// Copyright 2015-2016, Google Inc.
 // All rights reserved.
 //
 // Redistribution and use in source and binary forms, with or without
@@ -38,7 +38,7 @@
     /// <summary>
     /// Utility methods to simplify checking preconditions in the code.
     /// </summary>
-    public static class Preconditions
+    public static class GrpcPreconditions
     {
         /// <summary>
         /// Throws <see cref="ArgumentException"/> if condition is false.
diff --git a/src/csharp/Grpc.HealthCheck.Tests/HealthClientServerTest.cs b/src/csharp/Grpc.HealthCheck.Tests/HealthClientServerTest.cs
index a8a76c7..c3fac05 100644
--- a/src/csharp/Grpc.HealthCheck.Tests/HealthClientServerTest.cs
+++ b/src/csharp/Grpc.HealthCheck.Tests/HealthClientServerTest.cs
@@ -36,7 +36,7 @@
 using System.Threading.Tasks;
 
 using Grpc.Core;
-using Grpc.Health.V1Alpha;
+using Grpc.Health.V1;
 using NUnit.Framework;
 
 namespace Grpc.HealthCheck.Tests
@@ -49,7 +49,7 @@
         const string Host = "localhost";
         Server server;
         Channel channel;
-        Grpc.Health.V1Alpha.Health.IHealthClient client;
+        Grpc.Health.V1.Health.IHealthClient client;
         Grpc.HealthCheck.HealthServiceImpl serviceImpl;
 
         [TestFixtureSetUp]
@@ -59,13 +59,13 @@
 
             server = new Server
             {
-                Services = { Grpc.Health.V1Alpha.Health.BindService(serviceImpl) },
+                Services = { Grpc.Health.V1.Health.BindService(serviceImpl) },
                 Ports = { { Host, ServerPort.PickUnused, ServerCredentials.Insecure } }
             };
             server.Start();
             channel = new Channel(Host, server.Ports.Single().BoundPort, ChannelCredentials.Insecure);
 
-            client = Grpc.Health.V1Alpha.Health.NewClient(channel);
+            client = Grpc.Health.V1.Health.NewClient(channel);
         }
 
         [TestFixtureTearDown]
@@ -79,16 +79,16 @@
         [Test]
         public void ServiceIsRunning()
         {
-            serviceImpl.SetStatus("", "", HealthCheckResponse.Types.ServingStatus.SERVING);
+            serviceImpl.SetStatus("", HealthCheckResponse.Types.ServingStatus.SERVING);
 
-            var response = client.Check(new HealthCheckRequest { Host = "", Service = "" });
+            var response = client.Check(new HealthCheckRequest { Service = "" });
             Assert.AreEqual(HealthCheckResponse.Types.ServingStatus.SERVING, response.Status);
         }
 
         [Test]
         public void ServiceDoesntExist()
         {
-            Assert.Throws(Is.TypeOf(typeof(RpcException)).And.Property("Status").Property("StatusCode").EqualTo(StatusCode.NotFound), () => client.Check(new HealthCheckRequest { Host = "", Service = "nonexistent.service" }));
+            Assert.Throws(Is.TypeOf(typeof(RpcException)).And.Property("Status").Property("StatusCode").EqualTo(StatusCode.NotFound), () => client.Check(new HealthCheckRequest { Service = "nonexistent.service" }));
         }
 
         // TODO(jtattermusch): add test with timeout once timeouts are supported
diff --git a/src/csharp/Grpc.HealthCheck.Tests/HealthServiceImplTest.cs b/src/csharp/Grpc.HealthCheck.Tests/HealthServiceImplTest.cs
index 2097c0d..47e4b7c 100644
--- a/src/csharp/Grpc.HealthCheck.Tests/HealthServiceImplTest.cs
+++ b/src/csharp/Grpc.HealthCheck.Tests/HealthServiceImplTest.cs
@@ -1,5 +1,5 @@
 #region Copyright notice and license
-// Copyright 2015, Google Inc.
+// Copyright 2015-2016, Google Inc.
 // All rights reserved.
 //
 // Redistribution and use in source and binary forms, with or without
@@ -36,7 +36,7 @@
 using System.Threading.Tasks;
 
 using Grpc.Core;
-using Grpc.Health.V1Alpha;
+using Grpc.Health.V1;
 using NUnit.Framework;
 
 namespace Grpc.HealthCheck.Tests
@@ -50,58 +50,56 @@
         public void SetStatus()
         {
             var impl = new HealthServiceImpl();
-            impl.SetStatus("", "", HealthCheckResponse.Types.ServingStatus.SERVING);
-            Assert.AreEqual(HealthCheckResponse.Types.ServingStatus.SERVING, GetStatusHelper(impl, "", ""));
+            impl.SetStatus("", HealthCheckResponse.Types.ServingStatus.SERVING);
+            Assert.AreEqual(HealthCheckResponse.Types.ServingStatus.SERVING, GetStatusHelper(impl, ""));
 
-            impl.SetStatus("", "", HealthCheckResponse.Types.ServingStatus.NOT_SERVING);
-            Assert.AreEqual(HealthCheckResponse.Types.ServingStatus.NOT_SERVING, GetStatusHelper(impl, "", ""));
+            impl.SetStatus("", HealthCheckResponse.Types.ServingStatus.NOT_SERVING);
+            Assert.AreEqual(HealthCheckResponse.Types.ServingStatus.NOT_SERVING, GetStatusHelper(impl, ""));
 
-            impl.SetStatus("virtual-host", "", HealthCheckResponse.Types.ServingStatus.UNKNOWN);
-            Assert.AreEqual(HealthCheckResponse.Types.ServingStatus.UNKNOWN, GetStatusHelper(impl, "virtual-host", ""));
+            impl.SetStatus("", HealthCheckResponse.Types.ServingStatus.UNKNOWN);
+            Assert.AreEqual(HealthCheckResponse.Types.ServingStatus.UNKNOWN, GetStatusHelper(impl, ""));
 
-            impl.SetStatus("virtual-host", "grpc.test.TestService", HealthCheckResponse.Types.ServingStatus.SERVING);
-            Assert.AreEqual(HealthCheckResponse.Types.ServingStatus.SERVING, GetStatusHelper(impl, "virtual-host", "grpc.test.TestService"));
+            impl.SetStatus("grpc.test.TestService", HealthCheckResponse.Types.ServingStatus.SERVING);
+            Assert.AreEqual(HealthCheckResponse.Types.ServingStatus.SERVING, GetStatusHelper(impl, "grpc.test.TestService"));
         }
 
         [Test]
         public void ClearStatus()
         {
             var impl = new HealthServiceImpl();
-            impl.SetStatus("", "", HealthCheckResponse.Types.ServingStatus.SERVING);
-            impl.SetStatus("virtual-host", "", HealthCheckResponse.Types.ServingStatus.UNKNOWN);
+            impl.SetStatus("", HealthCheckResponse.Types.ServingStatus.SERVING);
+            impl.SetStatus("grpc.test.TestService", HealthCheckResponse.Types.ServingStatus.UNKNOWN);
 
-            impl.ClearStatus("", "");
+            impl.ClearStatus("");
 
-            Assert.Throws(Is.TypeOf(typeof(RpcException)).And.Property("Status").Property("StatusCode").EqualTo(StatusCode.NotFound), () => GetStatusHelper(impl, "", ""));
-            Assert.AreEqual(HealthCheckResponse.Types.ServingStatus.UNKNOWN, GetStatusHelper(impl, "virtual-host", ""));
+            Assert.Throws(Is.TypeOf(typeof(RpcException)).And.Property("Status").Property("StatusCode").EqualTo(StatusCode.NotFound), () => GetStatusHelper(impl, ""));
+            Assert.AreEqual(HealthCheckResponse.Types.ServingStatus.UNKNOWN, GetStatusHelper(impl, "grpc.test.TestService"));
         }
 
         [Test]
         public void ClearAll()
         {
             var impl = new HealthServiceImpl();
-            impl.SetStatus("", "", HealthCheckResponse.Types.ServingStatus.SERVING);
-            impl.SetStatus("virtual-host", "", HealthCheckResponse.Types.ServingStatus.UNKNOWN);
+            impl.SetStatus("", HealthCheckResponse.Types.ServingStatus.SERVING);
+            impl.SetStatus("grpc.test.TestService", HealthCheckResponse.Types.ServingStatus.UNKNOWN);
 
             impl.ClearAll();
-            Assert.Throws(typeof(RpcException), () => GetStatusHelper(impl, "", ""));
-            Assert.Throws(typeof(RpcException), () => GetStatusHelper(impl, "virtual-host", ""));
+            Assert.Throws(typeof(RpcException), () => GetStatusHelper(impl, ""));
+            Assert.Throws(typeof(RpcException), () => GetStatusHelper(impl, "grpc.test.TestService"));
         }
 
         [Test]
         public void NullsRejected()
         {
             var impl = new HealthServiceImpl();
-            Assert.Throws(typeof(ArgumentNullException), () => impl.SetStatus(null, "", HealthCheckResponse.Types.ServingStatus.SERVING));
-            Assert.Throws(typeof(ArgumentNullException), () => impl.SetStatus("", null, HealthCheckResponse.Types.ServingStatus.SERVING));
+            Assert.Throws(typeof(ArgumentNullException), () => impl.SetStatus(null, HealthCheckResponse.Types.ServingStatus.SERVING));
 
-            Assert.Throws(typeof(ArgumentNullException), () => impl.ClearStatus(null, ""));
-            Assert.Throws(typeof(ArgumentNullException), () => impl.ClearStatus("", null));
+            Assert.Throws(typeof(ArgumentNullException), () => impl.ClearStatus(null));
         }
 
-        private static HealthCheckResponse.Types.ServingStatus GetStatusHelper(HealthServiceImpl impl, string host, string service)
+        private static HealthCheckResponse.Types.ServingStatus GetStatusHelper(HealthServiceImpl impl, string service)
         {
-            return impl.Check(new HealthCheckRequest { Host = host, Service = service }, null).Result.Status;
+            return impl.Check(new HealthCheckRequest { Service = service }, null).Result.Status;
         }
     }
 }
diff --git a/src/csharp/Grpc.HealthCheck/Grpc.HealthCheck.nuspec b/src/csharp/Grpc.HealthCheck/Grpc.HealthCheck.nuspec
index 6638628..7b3b391 100644
--- a/src/csharp/Grpc.HealthCheck/Grpc.HealthCheck.nuspec
+++ b/src/csharp/Grpc.HealthCheck/Grpc.HealthCheck.nuspec
@@ -4,7 +4,7 @@
     <id>Grpc.HealthCheck</id>
     <title>gRPC C# Healthchecking</title>
     <summary>Implementation of gRPC health service</summary>
-    <description>Example implementation of grpc.health.v1alpha service that can be used for health-checking.</description>
+    <description>Example implementation of grpc.health.v1 service that can be used for health-checking.</description>
     <version>$version$</version>
     <authors>Google Inc.</authors>
     <owners>grpc-packages</owners>
diff --git a/src/csharp/Grpc.HealthCheck/Health.cs b/src/csharp/Grpc.HealthCheck/Health.cs
index 56673f1..d0d0c0b 100644
--- a/src/csharp/Grpc.HealthCheck/Health.cs
+++ b/src/csharp/Grpc.HealthCheck/Health.cs
@@ -7,7 +7,7 @@
 using pbc = global::Google.Protobuf.Collections;
 using pbr = global::Google.Protobuf.Reflection;
 using scg = global::System.Collections.Generic;
-namespace Grpc.Health.V1Alpha {
+namespace Grpc.Health.V1 {
 
   /// <summary>Holder for reflection information generated from health.proto</summary>
   [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
@@ -23,20 +23,19 @@
     static HealthReflection() {
       byte[] descriptorData = global::System.Convert.FromBase64String(
           string.Concat(
-            "CgxoZWFsdGgucHJvdG8SE2dycGMuaGVhbHRoLnYxYWxwaGEiMwoSSGVhbHRo",
-            "Q2hlY2tSZXF1ZXN0EgwKBGhvc3QYASABKAkSDwoHc2VydmljZRgCIAEoCSKZ",
-            "AQoTSGVhbHRoQ2hlY2tSZXNwb25zZRJGCgZzdGF0dXMYASABKA4yNi5ncnBj",
-            "LmhlYWx0aC52MWFscGhhLkhlYWx0aENoZWNrUmVzcG9uc2UuU2VydmluZ1N0",
-            "YXR1cyI6Cg1TZXJ2aW5nU3RhdHVzEgsKB1VOS05PV04QABILCgdTRVJWSU5H",
-            "EAESDwoLTk9UX1NFUlZJTkcQAjJkCgZIZWFsdGgSWgoFQ2hlY2sSJy5ncnBj",
-            "LmhlYWx0aC52MWFscGhhLkhlYWx0aENoZWNrUmVxdWVzdBooLmdycGMuaGVh",
-            "bHRoLnYxYWxwaGEuSGVhbHRoQ2hlY2tSZXNwb25zZUIWqgITR3JwYy5IZWFs",
-            "dGguVjFBbHBoYWIGcHJvdG8z"));
+            "CgxoZWFsdGgucHJvdG8SDmdycGMuaGVhbHRoLnYxIiUKEkhlYWx0aENoZWNr",
+            "UmVxdWVzdBIPCgdzZXJ2aWNlGAEgASgJIpQBChNIZWFsdGhDaGVja1Jlc3Bv",
+            "bnNlEkEKBnN0YXR1cxgBIAEoDjIxLmdycGMuaGVhbHRoLnYxLkhlYWx0aENo",
+            "ZWNrUmVzcG9uc2UuU2VydmluZ1N0YXR1cyI6Cg1TZXJ2aW5nU3RhdHVzEgsK",
+            "B1VOS05PV04QABILCgdTRVJWSU5HEAESDwoLTk9UX1NFUlZJTkcQAjJaCgZI",
+            "ZWFsdGgSUAoFQ2hlY2sSIi5ncnBjLmhlYWx0aC52MS5IZWFsdGhDaGVja1Jl",
+            "cXVlc3QaIy5ncnBjLmhlYWx0aC52MS5IZWFsdGhDaGVja1Jlc3BvbnNlQhGq",
+            "Ag5HcnBjLkhlYWx0aC5WMWIGcHJvdG8z"));
       descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
           new pbr::FileDescriptor[] { },
           new pbr::GeneratedCodeInfo(null, new pbr::GeneratedCodeInfo[] {
-            new pbr::GeneratedCodeInfo(typeof(global::Grpc.Health.V1Alpha.HealthCheckRequest), global::Grpc.Health.V1Alpha.HealthCheckRequest.Parser, new[]{ "Host", "Service" }, null, null, null),
-            new pbr::GeneratedCodeInfo(typeof(global::Grpc.Health.V1Alpha.HealthCheckResponse), global::Grpc.Health.V1Alpha.HealthCheckResponse.Parser, new[]{ "Status" }, null, new[]{ typeof(global::Grpc.Health.V1Alpha.HealthCheckResponse.Types.ServingStatus) }, null)
+            new pbr::GeneratedCodeInfo(typeof(global::Grpc.Health.V1.HealthCheckRequest), global::Grpc.Health.V1.HealthCheckRequest.Parser, new[]{ "Service" }, null, null, null),
+            new pbr::GeneratedCodeInfo(typeof(global::Grpc.Health.V1.HealthCheckResponse), global::Grpc.Health.V1.HealthCheckResponse.Parser, new[]{ "Status" }, null, new[]{ typeof(global::Grpc.Health.V1.HealthCheckResponse.Types.ServingStatus) }, null)
           }));
     }
     #endregion
@@ -49,7 +48,7 @@
     public static pb::MessageParser<HealthCheckRequest> Parser { get { return _parser; } }
 
     public static pbr::MessageDescriptor Descriptor {
-      get { return global::Grpc.Health.V1Alpha.HealthReflection.Descriptor.MessageTypes[0]; }
+      get { return global::Grpc.Health.V1.HealthReflection.Descriptor.MessageTypes[0]; }
     }
 
     pbr::MessageDescriptor pb::IMessage.Descriptor {
@@ -63,7 +62,6 @@
     partial void OnConstruction();
 
     public HealthCheckRequest(HealthCheckRequest other) : this() {
-      host_ = other.host_;
       service_ = other.service_;
     }
 
@@ -71,18 +69,8 @@
       return new HealthCheckRequest(this);
     }
 
-    /// <summary>Field number for the "host" field.</summary>
-    public const int HostFieldNumber = 1;
-    private string host_ = "";
-    public string Host {
-      get { return host_; }
-      set {
-        host_ = pb::Preconditions.CheckNotNull(value, "value");
-      }
-    }
-
     /// <summary>Field number for the "service" field.</summary>
-    public const int ServiceFieldNumber = 2;
+    public const int ServiceFieldNumber = 1;
     private string service_ = "";
     public string Service {
       get { return service_; }
@@ -102,14 +90,12 @@
       if (ReferenceEquals(other, this)) {
         return true;
       }
-      if (Host != other.Host) return false;
       if (Service != other.Service) return false;
       return true;
     }
 
     public override int GetHashCode() {
       int hash = 1;
-      if (Host.Length != 0) hash ^= Host.GetHashCode();
       if (Service.Length != 0) hash ^= Service.GetHashCode();
       return hash;
     }
@@ -119,21 +105,14 @@
     }
 
     public void WriteTo(pb::CodedOutputStream output) {
-      if (Host.Length != 0) {
-        output.WriteRawTag(10);
-        output.WriteString(Host);
-      }
       if (Service.Length != 0) {
-        output.WriteRawTag(18);
+        output.WriteRawTag(10);
         output.WriteString(Service);
       }
     }
 
     public int CalculateSize() {
       int size = 0;
-      if (Host.Length != 0) {
-        size += 1 + pb::CodedOutputStream.ComputeStringSize(Host);
-      }
       if (Service.Length != 0) {
         size += 1 + pb::CodedOutputStream.ComputeStringSize(Service);
       }
@@ -144,9 +123,6 @@
       if (other == null) {
         return;
       }
-      if (other.Host.Length != 0) {
-        Host = other.Host;
-      }
       if (other.Service.Length != 0) {
         Service = other.Service;
       }
@@ -160,10 +136,6 @@
             input.SkipLastField();
             break;
           case 10: {
-            Host = input.ReadString();
-            break;
-          }
-          case 18: {
             Service = input.ReadString();
             break;
           }
@@ -179,7 +151,7 @@
     public static pb::MessageParser<HealthCheckResponse> Parser { get { return _parser; } }
 
     public static pbr::MessageDescriptor Descriptor {
-      get { return global::Grpc.Health.V1Alpha.HealthReflection.Descriptor.MessageTypes[1]; }
+      get { return global::Grpc.Health.V1.HealthReflection.Descriptor.MessageTypes[1]; }
     }
 
     pbr::MessageDescriptor pb::IMessage.Descriptor {
@@ -202,8 +174,8 @@
 
     /// <summary>Field number for the "status" field.</summary>
     public const int StatusFieldNumber = 1;
-    private global::Grpc.Health.V1Alpha.HealthCheckResponse.Types.ServingStatus status_ = global::Grpc.Health.V1Alpha.HealthCheckResponse.Types.ServingStatus.UNKNOWN;
-    public global::Grpc.Health.V1Alpha.HealthCheckResponse.Types.ServingStatus Status {
+    private global::Grpc.Health.V1.HealthCheckResponse.Types.ServingStatus status_ = global::Grpc.Health.V1.HealthCheckResponse.Types.ServingStatus.UNKNOWN;
+    public global::Grpc.Health.V1.HealthCheckResponse.Types.ServingStatus Status {
       get { return status_; }
       set {
         status_ = value;
@@ -227,7 +199,7 @@
 
     public override int GetHashCode() {
       int hash = 1;
-      if (Status != global::Grpc.Health.V1Alpha.HealthCheckResponse.Types.ServingStatus.UNKNOWN) hash ^= Status.GetHashCode();
+      if (Status != global::Grpc.Health.V1.HealthCheckResponse.Types.ServingStatus.UNKNOWN) hash ^= Status.GetHashCode();
       return hash;
     }
 
@@ -236,7 +208,7 @@
     }
 
     public void WriteTo(pb::CodedOutputStream output) {
-      if (Status != global::Grpc.Health.V1Alpha.HealthCheckResponse.Types.ServingStatus.UNKNOWN) {
+      if (Status != global::Grpc.Health.V1.HealthCheckResponse.Types.ServingStatus.UNKNOWN) {
         output.WriteRawTag(8);
         output.WriteEnum((int) Status);
       }
@@ -244,7 +216,7 @@
 
     public int CalculateSize() {
       int size = 0;
-      if (Status != global::Grpc.Health.V1Alpha.HealthCheckResponse.Types.ServingStatus.UNKNOWN) {
+      if (Status != global::Grpc.Health.V1.HealthCheckResponse.Types.ServingStatus.UNKNOWN) {
         size += 1 + pb::CodedOutputStream.ComputeEnumSize((int) Status);
       }
       return size;
@@ -254,7 +226,7 @@
       if (other == null) {
         return;
       }
-      if (other.Status != global::Grpc.Health.V1Alpha.HealthCheckResponse.Types.ServingStatus.UNKNOWN) {
+      if (other.Status != global::Grpc.Health.V1.HealthCheckResponse.Types.ServingStatus.UNKNOWN) {
         Status = other.Status;
       }
     }
@@ -267,7 +239,7 @@
             input.SkipLastField();
             break;
           case 8: {
-            status_ = (global::Grpc.Health.V1Alpha.HealthCheckResponse.Types.ServingStatus) input.ReadEnum();
+            status_ = (global::Grpc.Health.V1.HealthCheckResponse.Types.ServingStatus) input.ReadEnum();
             break;
           }
         }
diff --git a/src/csharp/Grpc.HealthCheck/HealthGrpc.cs b/src/csharp/Grpc.HealthCheck/HealthGrpc.cs
index 882edd5..68320eb 100644
--- a/src/csharp/Grpc.HealthCheck/HealthGrpc.cs
+++ b/src/csharp/Grpc.HealthCheck/HealthGrpc.cs
@@ -7,15 +7,15 @@
 using System.Threading.Tasks;
 using Grpc.Core;
 
-namespace Grpc.Health.V1Alpha {
+namespace Grpc.Health.V1 {
   public static class Health
   {
-    static readonly string __ServiceName = "grpc.health.v1alpha.Health";
+    static readonly string __ServiceName = "grpc.health.v1.Health";
 
-    static readonly Marshaller<global::Grpc.Health.V1Alpha.HealthCheckRequest> __Marshaller_HealthCheckRequest = Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Health.V1Alpha.HealthCheckRequest.Parser.ParseFrom);
-    static readonly Marshaller<global::Grpc.Health.V1Alpha.HealthCheckResponse> __Marshaller_HealthCheckResponse = Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Health.V1Alpha.HealthCheckResponse.Parser.ParseFrom);
+    static readonly Marshaller<global::Grpc.Health.V1.HealthCheckRequest> __Marshaller_HealthCheckRequest = Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Health.V1.HealthCheckRequest.Parser.ParseFrom);
+    static readonly Marshaller<global::Grpc.Health.V1.HealthCheckResponse> __Marshaller_HealthCheckResponse = Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Health.V1.HealthCheckResponse.Parser.ParseFrom);
 
-    static readonly Method<global::Grpc.Health.V1Alpha.HealthCheckRequest, global::Grpc.Health.V1Alpha.HealthCheckResponse> __Method_Check = new Method<global::Grpc.Health.V1Alpha.HealthCheckRequest, global::Grpc.Health.V1Alpha.HealthCheckResponse>(
+    static readonly Method<global::Grpc.Health.V1.HealthCheckRequest, global::Grpc.Health.V1.HealthCheckResponse> __Method_Check = new Method<global::Grpc.Health.V1.HealthCheckRequest, global::Grpc.Health.V1.HealthCheckResponse>(
         MethodType.Unary,
         __ServiceName,
         "Check",
@@ -25,22 +25,22 @@
     // service descriptor
     public static global::Google.Protobuf.Reflection.ServiceDescriptor Descriptor
     {
-      get { return global::Grpc.Health.V1Alpha.HealthReflection.Descriptor.Services[0]; }
+      get { return global::Grpc.Health.V1.HealthReflection.Descriptor.Services[0]; }
     }
 
     // client interface
     public interface IHealthClient
     {
-      global::Grpc.Health.V1Alpha.HealthCheckResponse Check(global::Grpc.Health.V1Alpha.HealthCheckRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
-      global::Grpc.Health.V1Alpha.HealthCheckResponse Check(global::Grpc.Health.V1Alpha.HealthCheckRequest request, CallOptions options);
-      AsyncUnaryCall<global::Grpc.Health.V1Alpha.HealthCheckResponse> CheckAsync(global::Grpc.Health.V1Alpha.HealthCheckRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
-      AsyncUnaryCall<global::Grpc.Health.V1Alpha.HealthCheckResponse> CheckAsync(global::Grpc.Health.V1Alpha.HealthCheckRequest request, CallOptions options);
+      global::Grpc.Health.V1.HealthCheckResponse Check(global::Grpc.Health.V1.HealthCheckRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
+      global::Grpc.Health.V1.HealthCheckResponse Check(global::Grpc.Health.V1.HealthCheckRequest request, CallOptions options);
+      AsyncUnaryCall<global::Grpc.Health.V1.HealthCheckResponse> CheckAsync(global::Grpc.Health.V1.HealthCheckRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
+      AsyncUnaryCall<global::Grpc.Health.V1.HealthCheckResponse> CheckAsync(global::Grpc.Health.V1.HealthCheckRequest request, CallOptions options);
     }
 
     // server-side interface
     public interface IHealth
     {
-      Task<global::Grpc.Health.V1Alpha.HealthCheckResponse> Check(global::Grpc.Health.V1Alpha.HealthCheckRequest request, ServerCallContext context);
+      Task<global::Grpc.Health.V1.HealthCheckResponse> Check(global::Grpc.Health.V1.HealthCheckRequest request, ServerCallContext context);
     }
 
     // client stub
@@ -49,22 +49,22 @@
       public HealthClient(Channel channel) : base(channel)
       {
       }
-      public global::Grpc.Health.V1Alpha.HealthCheckResponse Check(global::Grpc.Health.V1Alpha.HealthCheckRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+      public global::Grpc.Health.V1.HealthCheckResponse Check(global::Grpc.Health.V1.HealthCheckRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
         var call = CreateCall(__Method_Check, new CallOptions(headers, deadline, cancellationToken));
         return Calls.BlockingUnaryCall(call, request);
       }
-      public global::Grpc.Health.V1Alpha.HealthCheckResponse Check(global::Grpc.Health.V1Alpha.HealthCheckRequest request, CallOptions options)
+      public global::Grpc.Health.V1.HealthCheckResponse Check(global::Grpc.Health.V1.HealthCheckRequest request, CallOptions options)
       {
         var call = CreateCall(__Method_Check, options);
         return Calls.BlockingUnaryCall(call, request);
       }
-      public AsyncUnaryCall<global::Grpc.Health.V1Alpha.HealthCheckResponse> CheckAsync(global::Grpc.Health.V1Alpha.HealthCheckRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+      public AsyncUnaryCall<global::Grpc.Health.V1.HealthCheckResponse> CheckAsync(global::Grpc.Health.V1.HealthCheckRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
         var call = CreateCall(__Method_Check, new CallOptions(headers, deadline, cancellationToken));
         return Calls.AsyncUnaryCall(call, request);
       }
-      public AsyncUnaryCall<global::Grpc.Health.V1Alpha.HealthCheckResponse> CheckAsync(global::Grpc.Health.V1Alpha.HealthCheckRequest request, CallOptions options)
+      public AsyncUnaryCall<global::Grpc.Health.V1.HealthCheckResponse> CheckAsync(global::Grpc.Health.V1.HealthCheckRequest request, CallOptions options)
       {
         var call = CreateCall(__Method_Check, options);
         return Calls.AsyncUnaryCall(call, request);
diff --git a/src/csharp/Grpc.HealthCheck/HealthServiceImpl.cs b/src/csharp/Grpc.HealthCheck/HealthServiceImpl.cs
index 26c6445..21482b3 100644
--- a/src/csharp/Grpc.HealthCheck/HealthServiceImpl.cs
+++ b/src/csharp/Grpc.HealthCheck/HealthServiceImpl.cs
@@ -1,5 +1,5 @@
 #region Copyright notice and license
-// Copyright 2015, Google Inc.
+// Copyright 2015-2016, Google Inc.
 // All rights reserved.
 //
 // Redistribution and use in source and binary forms, with or without
@@ -37,7 +37,7 @@
 
 using Grpc.Core;
 using Grpc.Core.Utils;
-using Grpc.Health.V1Alpha;
+using Grpc.Health.V1;
 
 namespace Grpc.HealthCheck
 {
@@ -48,44 +48,42 @@
     /// <code>
     /// var serviceImpl = new HealthServiceImpl();
     /// server = new Server();
-    /// server.AddServiceDefinition(Grpc.Health.V1Alpha.Health.BindService(serviceImpl));
+    /// server.AddServiceDefinition(Grpc.Health.V1.Health.BindService(serviceImpl));
     /// </code>
     /// </summary>
-    public class HealthServiceImpl : Grpc.Health.V1Alpha.Health.IHealth
+    public class HealthServiceImpl : Grpc.Health.V1.Health.IHealth
     {
         private readonly object myLock = new object();
-        private readonly Dictionary<Key, HealthCheckResponse.Types.ServingStatus> statusMap = 
-            new Dictionary<Key, HealthCheckResponse.Types.ServingStatus>();
+        private readonly Dictionary<string, HealthCheckResponse.Types.ServingStatus> statusMap = 
+            new Dictionary<string, HealthCheckResponse.Types.ServingStatus>();
 
         /// <summary>
-        /// Sets the health status for given host and service.
+        /// Sets the health status for given service.
         /// </summary>
-        /// <param name="host">The host. Cannot be null.</param>
         /// <param name="service">The service. Cannot be null.</param>
         /// <param name="status">the health status</param>
-        public void SetStatus(string host, string service, HealthCheckResponse.Types.ServingStatus status)
+        public void SetStatus(string service, HealthCheckResponse.Types.ServingStatus status)
         {
             lock (myLock)
             {
-                statusMap[CreateKey(host, service)] = status;
+                statusMap[service] = status;
             }
         }
 
         /// <summary>
-        /// Clears health status for given host and service.
+        /// Clears health status for given service.
         /// </summary>
-        /// <param name="host">The host. Cannot be null.</param>
         /// <param name="service">The service. Cannot be null.</param>
-        public void ClearStatus(string host, string service)
+        public void ClearStatus(string service)
         {
             lock (myLock)
             {
-                statusMap.Remove(CreateKey(host, service));
+                statusMap.Remove(service);
             }
         }
         
         /// <summary>
-        /// Clears statuses for all hosts and services.
+        /// Clears statuses for all services.
         /// </summary>
         public void ClearAll()
         {
@@ -105,11 +103,10 @@
         {
             lock (myLock)
             {
-                var host = request.Host;
                 var service = request.Service;
 
                 HealthCheckResponse.Types.ServingStatus status;
-                if (!statusMap.TryGetValue(CreateKey(host, service), out status))
+                if (!statusMap.TryGetValue(service, out status))
                 {
                     // TODO(jtattermusch): returning specific status from server handler is not supported yet.
                     throw new RpcException(new Status(StatusCode.NotFound, ""));
@@ -117,22 +114,5 @@
                 return Task.FromResult(new HealthCheckResponse { Status = status });
             }
         }
-
-        private static Key CreateKey(string host, string service)
-        {
-            return new Key(host, service);
-        }
-
-        private struct Key
-        {
-            public Key(string host, string service)
-            {
-                this.Host = Preconditions.CheckNotNull(host);
-                this.Service = Preconditions.CheckNotNull(service);
-            }
-
-            readonly string Host;
-            readonly string Service;
-        }
     }
 }
diff --git a/src/csharp/Grpc.IntegrationTesting/ClientRunners.cs b/src/csharp/Grpc.IntegrationTesting/ClientRunners.cs
index e9e659c..c401601 100644
--- a/src/csharp/Grpc.IntegrationTesting/ClientRunners.cs
+++ b/src/csharp/Grpc.IntegrationTesting/ClientRunners.cs
@@ -1,6 +1,6 @@
 #region Copyright notice and license
 
-// Copyright 2015, Google Inc.
+// Copyright 2015-2016, Google Inc.
 // All rights reserved.
 //
 // Redistribution and use in source and binary forms, with or without
@@ -58,7 +58,7 @@
         public static IClientRunner CreateStarted(ClientConfig config)
         {
             string target = config.ServerTargets.Single();
-            Grpc.Core.Utils.Preconditions.CheckArgument(config.LoadParams.LoadCase == LoadParams.LoadOneofCase.ClosedLoop);
+            GrpcPreconditions.CheckArgument(config.LoadParams.LoadCase == LoadParams.LoadOneofCase.ClosedLoop);
 
             var credentials = config.SecurityParams != null ? TestCredentials.CreateSslCredentials() : ChannelCredentials.Insecure;
             var channel = new Channel(target, credentials);
@@ -95,7 +95,7 @@
         
         public SyncUnaryClientRunner(Channel channel, int payloadSize, HistogramParams histogramParams)
         {
-            this.channel = Grpc.Core.Utils.Preconditions.CheckNotNull(channel);
+            this.channel = GrpcPreconditions.CheckNotNull(channel);
             this.payloadSize = payloadSize;
             this.histogram = new Histogram(histogramParams.Resolution, histogramParams.MaxPossible);
 
diff --git a/src/csharp/Grpc.IntegrationTesting/Control.cs b/src/csharp/Grpc.IntegrationTesting/Control.cs
index b90243c..291bc75 100644
--- a/src/csharp/Grpc.IntegrationTesting/Control.cs
+++ b/src/csharp/Grpc.IntegrationTesting/Control.cs
@@ -38,7 +38,7 @@
             "LmdycGMudGVzdGluZy5EZXRlcm1pbmlzdGljUGFyYW1zSAASLAoGcGFyZXRv",
             "GAUgASgLMhouZ3JwYy50ZXN0aW5nLlBhcmV0b1BhcmFtc0gAQgYKBGxvYWQi",
             "QwoOU2VjdXJpdHlQYXJhbXMSEwoLdXNlX3Rlc3RfY2EYASABKAgSHAoUc2Vy",
-            "dmVyX2hvc3Rfb3ZlcnJpZGUYAiABKAkirwMKDENsaWVudENvbmZpZxIWCg5z",
+            "dmVyX2hvc3Rfb3ZlcnJpZGUYAiABKAki1gMKDENsaWVudENvbmZpZxIWCg5z",
             "ZXJ2ZXJfdGFyZ2V0cxgBIAMoCRItCgtjbGllbnRfdHlwZRgCIAEoDjIYLmdy",
             "cGMudGVzdGluZy5DbGllbnRUeXBlEjUKD3NlY3VyaXR5X3BhcmFtcxgDIAEo",
             "CzIcLmdycGMudGVzdGluZy5TZWN1cml0eVBhcmFtcxIkChxvdXRzdGFuZGlu",
@@ -48,24 +48,27 @@
             "GAogASgLMhguZ3JwYy50ZXN0aW5nLkxvYWRQYXJhbXMSMwoOcGF5bG9hZF9j",
             "b25maWcYCyABKAsyGy5ncnBjLnRlc3RpbmcuUGF5bG9hZENvbmZpZxI3ChBo",
             "aXN0b2dyYW1fcGFyYW1zGAwgASgLMh0uZ3JwYy50ZXN0aW5nLkhpc3RvZ3Jh",
-            "bVBhcmFtcyI4CgxDbGllbnRTdGF0dXMSKAoFc3RhdHMYASABKAsyGS5ncnBj",
-            "LnRlc3RpbmcuQ2xpZW50U3RhdHMiFQoETWFyaxINCgVyZXNldBgBIAEoCCJo",
-            "CgpDbGllbnRBcmdzEisKBXNldHVwGAEgASgLMhouZ3JwYy50ZXN0aW5nLkNs",
-            "aWVudENvbmZpZ0gAEiIKBG1hcmsYAiABKAsyEi5ncnBjLnRlc3RpbmcuTWFy",
-            "a0gAQgkKB2FyZ3R5cGUi9wEKDFNlcnZlckNvbmZpZxItCgtzZXJ2ZXJfdHlw",
-            "ZRgBIAEoDjIYLmdycGMudGVzdGluZy5TZXJ2ZXJUeXBlEjUKD3NlY3VyaXR5",
-            "X3BhcmFtcxgCIAEoCzIcLmdycGMudGVzdGluZy5TZWN1cml0eVBhcmFtcxIM",
-            "CgRob3N0GAMgASgJEgwKBHBvcnQYBCABKAUSHAoUYXN5bmNfc2VydmVyX3Ro",
-            "cmVhZHMYByABKAUSEgoKY29yZV9saW1pdBgIIAEoBRIzCg5wYXlsb2FkX2Nv",
-            "bmZpZxgJIAEoCzIbLmdycGMudGVzdGluZy5QYXlsb2FkQ29uZmlnImgKClNl",
-            "cnZlckFyZ3MSKwoFc2V0dXAYASABKAsyGi5ncnBjLnRlc3RpbmcuU2VydmVy",
-            "Q29uZmlnSAASIgoEbWFyaxgCIAEoCzISLmdycGMudGVzdGluZy5NYXJrSABC",
-            "CQoHYXJndHlwZSJVCgxTZXJ2ZXJTdGF0dXMSKAoFc3RhdHMYASABKAsyGS5n",
-            "cnBjLnRlc3RpbmcuU2VydmVyU3RhdHMSDAoEcG9ydBgCIAEoBRINCgVjb3Jl",
-            "cxgDIAEoBSovCgpDbGllbnRUeXBlEg8KC1NZTkNfQ0xJRU5UEAASEAoMQVNZ",
-            "TkNfQ0xJRU5UEAEqLwoKU2VydmVyVHlwZRIPCgtTWU5DX1NFUlZFUhAAEhAK",
-            "DEFTWU5DX1NFUlZFUhABKiMKB1JwY1R5cGUSCQoFVU5BUlkQABINCglTVFJF",
-            "QU1JTkcQAWIGcHJvdG8z"));
+            "bVBhcmFtcxIRCgljb3JlX2xpc3QYDSADKAUSEgoKY29yZV9saW1pdBgOIAEo",
+            "BSI4CgxDbGllbnRTdGF0dXMSKAoFc3RhdHMYASABKAsyGS5ncnBjLnRlc3Rp",
+            "bmcuQ2xpZW50U3RhdHMiFQoETWFyaxINCgVyZXNldBgBIAEoCCJoCgpDbGll",
+            "bnRBcmdzEisKBXNldHVwGAEgASgLMhouZ3JwYy50ZXN0aW5nLkNsaWVudENv",
+            "bmZpZ0gAEiIKBG1hcmsYAiABKAsyEi5ncnBjLnRlc3RpbmcuTWFya0gAQgkK",
+            "B2FyZ3R5cGUi/AEKDFNlcnZlckNvbmZpZxItCgtzZXJ2ZXJfdHlwZRgBIAEo",
+            "DjIYLmdycGMudGVzdGluZy5TZXJ2ZXJUeXBlEjUKD3NlY3VyaXR5X3BhcmFt",
+            "cxgCIAEoCzIcLmdycGMudGVzdGluZy5TZWN1cml0eVBhcmFtcxIMCgRwb3J0",
+            "GAQgASgFEhwKFGFzeW5jX3NlcnZlcl90aHJlYWRzGAcgASgFEhIKCmNvcmVf",
+            "bGltaXQYCCABKAUSMwoOcGF5bG9hZF9jb25maWcYCSABKAsyGy5ncnBjLnRl",
+            "c3RpbmcuUGF5bG9hZENvbmZpZxIRCgljb3JlX2xpc3QYCiADKAUiaAoKU2Vy",
+            "dmVyQXJncxIrCgVzZXR1cBgBIAEoCzIaLmdycGMudGVzdGluZy5TZXJ2ZXJD",
+            "b25maWdIABIiCgRtYXJrGAIgASgLMhIuZ3JwYy50ZXN0aW5nLk1hcmtIAEIJ",
+            "Cgdhcmd0eXBlIlUKDFNlcnZlclN0YXR1cxIoCgVzdGF0cxgBIAEoCzIZLmdy",
+            "cGMudGVzdGluZy5TZXJ2ZXJTdGF0cxIMCgRwb3J0GAIgASgFEg0KBWNvcmVz",
+            "GAMgASgFIg0KC0NvcmVSZXF1ZXN0Ih0KDENvcmVSZXNwb25zZRINCgVjb3Jl",
+            "cxgBIAEoBSIGCgRWb2lkKi8KCkNsaWVudFR5cGUSDwoLU1lOQ19DTElFTlQQ",
+            "ABIQCgxBU1lOQ19DTElFTlQQASpJCgpTZXJ2ZXJUeXBlEg8KC1NZTkNfU0VS",
+            "VkVSEAASEAoMQVNZTkNfU0VSVkVSEAESGAoUQVNZTkNfR0VORVJJQ19TRVJW",
+            "RVIQAiojCgdScGNUeXBlEgkKBVVOQVJZEAASDQoJU1RSRUFNSU5HEAFiBnBy",
+            "b3RvMw=="));
       descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
           new pbr::FileDescriptor[] { global::Grpc.Testing.PayloadsReflection.Descriptor, global::Grpc.Testing.StatsReflection.Descriptor, },
           new pbr::GeneratedCodeInfo(new[] {typeof(global::Grpc.Testing.ClientType), typeof(global::Grpc.Testing.ServerType), typeof(global::Grpc.Testing.RpcType), }, new pbr::GeneratedCodeInfo[] {
@@ -76,13 +79,16 @@
             new pbr::GeneratedCodeInfo(typeof(global::Grpc.Testing.ClosedLoopParams), global::Grpc.Testing.ClosedLoopParams.Parser, null, null, null, null),
             new pbr::GeneratedCodeInfo(typeof(global::Grpc.Testing.LoadParams), global::Grpc.Testing.LoadParams.Parser, new[]{ "ClosedLoop", "Poisson", "Uniform", "Determ", "Pareto" }, new[]{ "Load" }, null, null),
             new pbr::GeneratedCodeInfo(typeof(global::Grpc.Testing.SecurityParams), global::Grpc.Testing.SecurityParams.Parser, new[]{ "UseTestCa", "ServerHostOverride" }, null, null, null),
-            new pbr::GeneratedCodeInfo(typeof(global::Grpc.Testing.ClientConfig), global::Grpc.Testing.ClientConfig.Parser, new[]{ "ServerTargets", "ClientType", "SecurityParams", "OutstandingRpcsPerChannel", "ClientChannels", "AsyncClientThreads", "RpcType", "LoadParams", "PayloadConfig", "HistogramParams" }, null, null, null),
+            new pbr::GeneratedCodeInfo(typeof(global::Grpc.Testing.ClientConfig), global::Grpc.Testing.ClientConfig.Parser, new[]{ "ServerTargets", "ClientType", "SecurityParams", "OutstandingRpcsPerChannel", "ClientChannels", "AsyncClientThreads", "RpcType", "LoadParams", "PayloadConfig", "HistogramParams", "CoreList", "CoreLimit" }, null, null, null),
             new pbr::GeneratedCodeInfo(typeof(global::Grpc.Testing.ClientStatus), global::Grpc.Testing.ClientStatus.Parser, new[]{ "Stats" }, null, null, null),
             new pbr::GeneratedCodeInfo(typeof(global::Grpc.Testing.Mark), global::Grpc.Testing.Mark.Parser, new[]{ "Reset" }, null, null, null),
             new pbr::GeneratedCodeInfo(typeof(global::Grpc.Testing.ClientArgs), global::Grpc.Testing.ClientArgs.Parser, new[]{ "Setup", "Mark" }, new[]{ "Argtype" }, null, null),
-            new pbr::GeneratedCodeInfo(typeof(global::Grpc.Testing.ServerConfig), global::Grpc.Testing.ServerConfig.Parser, new[]{ "ServerType", "SecurityParams", "Host", "Port", "AsyncServerThreads", "CoreLimit", "PayloadConfig" }, null, null, null),
+            new pbr::GeneratedCodeInfo(typeof(global::Grpc.Testing.ServerConfig), global::Grpc.Testing.ServerConfig.Parser, new[]{ "ServerType", "SecurityParams", "Port", "AsyncServerThreads", "CoreLimit", "PayloadConfig", "CoreList" }, null, null, null),
             new pbr::GeneratedCodeInfo(typeof(global::Grpc.Testing.ServerArgs), global::Grpc.Testing.ServerArgs.Parser, new[]{ "Setup", "Mark" }, new[]{ "Argtype" }, null, null),
-            new pbr::GeneratedCodeInfo(typeof(global::Grpc.Testing.ServerStatus), global::Grpc.Testing.ServerStatus.Parser, new[]{ "Stats", "Port", "Cores" }, null, null, null)
+            new pbr::GeneratedCodeInfo(typeof(global::Grpc.Testing.ServerStatus), global::Grpc.Testing.ServerStatus.Parser, new[]{ "Stats", "Port", "Cores" }, null, null, null),
+            new pbr::GeneratedCodeInfo(typeof(global::Grpc.Testing.CoreRequest), global::Grpc.Testing.CoreRequest.Parser, null, null, null, null),
+            new pbr::GeneratedCodeInfo(typeof(global::Grpc.Testing.CoreResponse), global::Grpc.Testing.CoreResponse.Parser, new[]{ "Cores" }, null, null, null),
+            new pbr::GeneratedCodeInfo(typeof(global::Grpc.Testing.Void), global::Grpc.Testing.Void.Parser, null, null, null, null)
           }));
     }
     #endregion
@@ -97,6 +103,7 @@
   public enum ServerType {
     SYNC_SERVER = 0,
     ASYNC_SERVER = 1,
+    ASYNC_GENERIC_SERVER = 2,
   }
 
   public enum RpcType {
@@ -1097,6 +1104,8 @@
       LoadParams = other.loadParams_ != null ? other.LoadParams.Clone() : null;
       PayloadConfig = other.payloadConfig_ != null ? other.PayloadConfig.Clone() : null;
       HistogramParams = other.histogramParams_ != null ? other.HistogramParams.Clone() : null;
+      coreList_ = other.coreList_.Clone();
+      coreLimit_ = other.coreLimit_;
     }
 
     public ClientConfig Clone() {
@@ -1219,6 +1228,28 @@
       }
     }
 
+    /// <summary>Field number for the "core_list" field.</summary>
+    public const int CoreListFieldNumber = 13;
+    private static readonly pb::FieldCodec<int> _repeated_coreList_codec
+        = pb::FieldCodec.ForInt32(106);
+    private readonly pbc::RepeatedField<int> coreList_ = new pbc::RepeatedField<int>();
+    /// <summary>
+    ///  Specify the cores we should run the client on, if desired
+    /// </summary>
+    public pbc::RepeatedField<int> CoreList {
+      get { return coreList_; }
+    }
+
+    /// <summary>Field number for the "core_limit" field.</summary>
+    public const int CoreLimitFieldNumber = 14;
+    private int coreLimit_;
+    public int CoreLimit {
+      get { return coreLimit_; }
+      set {
+        coreLimit_ = value;
+      }
+    }
+
     public override bool Equals(object other) {
       return Equals(other as ClientConfig);
     }
@@ -1240,6 +1271,8 @@
       if (!object.Equals(LoadParams, other.LoadParams)) return false;
       if (!object.Equals(PayloadConfig, other.PayloadConfig)) return false;
       if (!object.Equals(HistogramParams, other.HistogramParams)) return false;
+      if(!coreList_.Equals(other.coreList_)) return false;
+      if (CoreLimit != other.CoreLimit) return false;
       return true;
     }
 
@@ -1255,6 +1288,8 @@
       if (loadParams_ != null) hash ^= LoadParams.GetHashCode();
       if (payloadConfig_ != null) hash ^= PayloadConfig.GetHashCode();
       if (histogramParams_ != null) hash ^= HistogramParams.GetHashCode();
+      hash ^= coreList_.GetHashCode();
+      if (CoreLimit != 0) hash ^= CoreLimit.GetHashCode();
       return hash;
     }
 
@@ -1300,6 +1335,11 @@
         output.WriteRawTag(98);
         output.WriteMessage(HistogramParams);
       }
+      coreList_.WriteTo(output, _repeated_coreList_codec);
+      if (CoreLimit != 0) {
+        output.WriteRawTag(112);
+        output.WriteInt32(CoreLimit);
+      }
     }
 
     public int CalculateSize() {
@@ -1332,6 +1372,10 @@
       if (histogramParams_ != null) {
         size += 1 + pb::CodedOutputStream.ComputeMessageSize(HistogramParams);
       }
+      size += coreList_.CalculateSize(_repeated_coreList_codec);
+      if (CoreLimit != 0) {
+        size += 1 + pb::CodedOutputStream.ComputeInt32Size(CoreLimit);
+      }
       return size;
     }
 
@@ -1379,6 +1423,10 @@
         }
         HistogramParams.MergeFrom(other.HistogramParams);
       }
+      coreList_.Add(other.coreList_);
+      if (other.CoreLimit != 0) {
+        CoreLimit = other.CoreLimit;
+      }
     }
 
     public void MergeFrom(pb::CodedInputStream input) {
@@ -1440,6 +1488,15 @@
             input.ReadMessage(histogramParams_);
             break;
           }
+          case 106:
+          case 104: {
+            coreList_.AddEntriesFrom(input, _repeated_coreList_codec);
+            break;
+          }
+          case 112: {
+            CoreLimit = input.ReadInt32();
+            break;
+          }
         }
       }
     }
@@ -1855,11 +1912,11 @@
     public ServerConfig(ServerConfig other) : this() {
       serverType_ = other.serverType_;
       SecurityParams = other.securityParams_ != null ? other.SecurityParams.Clone() : null;
-      host_ = other.host_;
       port_ = other.port_;
       asyncServerThreads_ = other.asyncServerThreads_;
       coreLimit_ = other.coreLimit_;
       PayloadConfig = other.payloadConfig_ != null ? other.PayloadConfig.Clone() : null;
+      coreList_ = other.coreList_.Clone();
     }
 
     public ServerConfig Clone() {
@@ -1886,19 +1943,6 @@
       }
     }
 
-    /// <summary>Field number for the "host" field.</summary>
-    public const int HostFieldNumber = 3;
-    private string host_ = "";
-    /// <summary>
-    ///  Host on which to listen.
-    /// </summary>
-    public string Host {
-      get { return host_; }
-      set {
-        host_ = pb::Preconditions.CheckNotNull(value, "value");
-      }
-    }
-
     /// <summary>Field number for the "port" field.</summary>
     public const int PortFieldNumber = 4;
     private int port_;
@@ -1929,7 +1973,7 @@
     public const int CoreLimitFieldNumber = 8;
     private int coreLimit_;
     /// <summary>
-    ///  restrict core usage, currently unused
+    ///  Specify the number of cores to limit server to, if desired
     /// </summary>
     public int CoreLimit {
       get { return coreLimit_; }
@@ -1941,6 +1985,9 @@
     /// <summary>Field number for the "payload_config" field.</summary>
     public const int PayloadConfigFieldNumber = 9;
     private global::Grpc.Testing.PayloadConfig payloadConfig_;
+    /// <summary>
+    ///  payload config, used in generic server
+    /// </summary>
     public global::Grpc.Testing.PayloadConfig PayloadConfig {
       get { return payloadConfig_; }
       set {
@@ -1948,6 +1995,18 @@
       }
     }
 
+    /// <summary>Field number for the "core_list" field.</summary>
+    public const int CoreListFieldNumber = 10;
+    private static readonly pb::FieldCodec<int> _repeated_coreList_codec
+        = pb::FieldCodec.ForInt32(82);
+    private readonly pbc::RepeatedField<int> coreList_ = new pbc::RepeatedField<int>();
+    /// <summary>
+    ///  Specify the cores we should run the server on, if desired
+    /// </summary>
+    public pbc::RepeatedField<int> CoreList {
+      get { return coreList_; }
+    }
+
     public override bool Equals(object other) {
       return Equals(other as ServerConfig);
     }
@@ -1961,11 +2020,11 @@
       }
       if (ServerType != other.ServerType) return false;
       if (!object.Equals(SecurityParams, other.SecurityParams)) return false;
-      if (Host != other.Host) return false;
       if (Port != other.Port) return false;
       if (AsyncServerThreads != other.AsyncServerThreads) return false;
       if (CoreLimit != other.CoreLimit) return false;
       if (!object.Equals(PayloadConfig, other.PayloadConfig)) return false;
+      if(!coreList_.Equals(other.coreList_)) return false;
       return true;
     }
 
@@ -1973,11 +2032,11 @@
       int hash = 1;
       if (ServerType != global::Grpc.Testing.ServerType.SYNC_SERVER) hash ^= ServerType.GetHashCode();
       if (securityParams_ != null) hash ^= SecurityParams.GetHashCode();
-      if (Host.Length != 0) hash ^= Host.GetHashCode();
       if (Port != 0) hash ^= Port.GetHashCode();
       if (AsyncServerThreads != 0) hash ^= AsyncServerThreads.GetHashCode();
       if (CoreLimit != 0) hash ^= CoreLimit.GetHashCode();
       if (payloadConfig_ != null) hash ^= PayloadConfig.GetHashCode();
+      hash ^= coreList_.GetHashCode();
       return hash;
     }
 
@@ -1994,10 +2053,6 @@
         output.WriteRawTag(18);
         output.WriteMessage(SecurityParams);
       }
-      if (Host.Length != 0) {
-        output.WriteRawTag(26);
-        output.WriteString(Host);
-      }
       if (Port != 0) {
         output.WriteRawTag(32);
         output.WriteInt32(Port);
@@ -2014,6 +2069,7 @@
         output.WriteRawTag(74);
         output.WriteMessage(PayloadConfig);
       }
+      coreList_.WriteTo(output, _repeated_coreList_codec);
     }
 
     public int CalculateSize() {
@@ -2024,9 +2080,6 @@
       if (securityParams_ != null) {
         size += 1 + pb::CodedOutputStream.ComputeMessageSize(SecurityParams);
       }
-      if (Host.Length != 0) {
-        size += 1 + pb::CodedOutputStream.ComputeStringSize(Host);
-      }
       if (Port != 0) {
         size += 1 + pb::CodedOutputStream.ComputeInt32Size(Port);
       }
@@ -2039,6 +2092,7 @@
       if (payloadConfig_ != null) {
         size += 1 + pb::CodedOutputStream.ComputeMessageSize(PayloadConfig);
       }
+      size += coreList_.CalculateSize(_repeated_coreList_codec);
       return size;
     }
 
@@ -2055,9 +2109,6 @@
         }
         SecurityParams.MergeFrom(other.SecurityParams);
       }
-      if (other.Host.Length != 0) {
-        Host = other.Host;
-      }
       if (other.Port != 0) {
         Port = other.Port;
       }
@@ -2073,6 +2124,7 @@
         }
         PayloadConfig.MergeFrom(other.PayloadConfig);
       }
+      coreList_.Add(other.coreList_);
     }
 
     public void MergeFrom(pb::CodedInputStream input) {
@@ -2093,10 +2145,6 @@
             input.ReadMessage(securityParams_);
             break;
           }
-          case 26: {
-            Host = input.ReadString();
-            break;
-          }
           case 32: {
             Port = input.ReadInt32();
             break;
@@ -2116,6 +2164,11 @@
             input.ReadMessage(payloadConfig_);
             break;
           }
+          case 82:
+          case 80: {
+            coreList_.AddEntriesFrom(input, _repeated_coreList_codec);
+            break;
+          }
         }
       }
     }
@@ -2347,7 +2400,7 @@
     public const int CoresFieldNumber = 3;
     private int cores_;
     /// <summary>
-    ///  Number of cores on the server. See gpr_cpu_num_cores.
+    ///  Number of cores available to the server
     /// </summary>
     public int Cores {
       get { return cores_; }
@@ -2460,6 +2513,264 @@
 
   }
 
+  [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());
+    public static pb::MessageParser<CoreRequest> Parser { get { return _parser; } }
+
+    public static pbr::MessageDescriptor Descriptor {
+      get { return global::Grpc.Testing.ControlReflection.Descriptor.MessageTypes[14]; }
+    }
+
+    pbr::MessageDescriptor pb::IMessage.Descriptor {
+      get { return Descriptor; }
+    }
+
+    public CoreRequest() {
+      OnConstruction();
+    }
+
+    partial void OnConstruction();
+
+    public CoreRequest(CoreRequest other) : this() {
+    }
+
+    public CoreRequest Clone() {
+      return new CoreRequest(this);
+    }
+
+    public override bool Equals(object other) {
+      return Equals(other as CoreRequest);
+    }
+
+    public bool Equals(CoreRequest other) {
+      if (ReferenceEquals(other, null)) {
+        return false;
+      }
+      if (ReferenceEquals(other, this)) {
+        return true;
+      }
+      return true;
+    }
+
+    public override int GetHashCode() {
+      int hash = 1;
+      return hash;
+    }
+
+    public override string ToString() {
+      return pb::JsonFormatter.ToDiagnosticString(this);
+    }
+
+    public void WriteTo(pb::CodedOutputStream output) {
+    }
+
+    public int CalculateSize() {
+      int size = 0;
+      return size;
+    }
+
+    public void MergeFrom(CoreRequest other) {
+      if (other == null) {
+        return;
+      }
+    }
+
+    public void MergeFrom(pb::CodedInputStream input) {
+      uint tag;
+      while ((tag = input.ReadTag()) != 0) {
+        switch(tag) {
+          default:
+            input.SkipLastField();
+            break;
+        }
+      }
+    }
+
+  }
+
+  [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());
+    public static pb::MessageParser<CoreResponse> Parser { get { return _parser; } }
+
+    public static pbr::MessageDescriptor Descriptor {
+      get { return global::Grpc.Testing.ControlReflection.Descriptor.MessageTypes[15]; }
+    }
+
+    pbr::MessageDescriptor pb::IMessage.Descriptor {
+      get { return Descriptor; }
+    }
+
+    public CoreResponse() {
+      OnConstruction();
+    }
+
+    partial void OnConstruction();
+
+    public CoreResponse(CoreResponse other) : this() {
+      cores_ = other.cores_;
+    }
+
+    public CoreResponse Clone() {
+      return new CoreResponse(this);
+    }
+
+    /// <summary>Field number for the "cores" field.</summary>
+    public const int CoresFieldNumber = 1;
+    private int cores_;
+    /// <summary>
+    ///  Number of cores available on the server
+    /// </summary>
+    public int Cores {
+      get { return cores_; }
+      set {
+        cores_ = value;
+      }
+    }
+
+    public override bool Equals(object other) {
+      return Equals(other as CoreResponse);
+    }
+
+    public bool Equals(CoreResponse other) {
+      if (ReferenceEquals(other, null)) {
+        return false;
+      }
+      if (ReferenceEquals(other, this)) {
+        return true;
+      }
+      if (Cores != other.Cores) return false;
+      return true;
+    }
+
+    public override int GetHashCode() {
+      int hash = 1;
+      if (Cores != 0) hash ^= Cores.GetHashCode();
+      return hash;
+    }
+
+    public override string ToString() {
+      return pb::JsonFormatter.ToDiagnosticString(this);
+    }
+
+    public void WriteTo(pb::CodedOutputStream output) {
+      if (Cores != 0) {
+        output.WriteRawTag(8);
+        output.WriteInt32(Cores);
+      }
+    }
+
+    public int CalculateSize() {
+      int size = 0;
+      if (Cores != 0) {
+        size += 1 + pb::CodedOutputStream.ComputeInt32Size(Cores);
+      }
+      return size;
+    }
+
+    public void MergeFrom(CoreResponse other) {
+      if (other == null) {
+        return;
+      }
+      if (other.Cores != 0) {
+        Cores = other.Cores;
+      }
+    }
+
+    public void MergeFrom(pb::CodedInputStream input) {
+      uint tag;
+      while ((tag = input.ReadTag()) != 0) {
+        switch(tag) {
+          default:
+            input.SkipLastField();
+            break;
+          case 8: {
+            Cores = input.ReadInt32();
+            break;
+          }
+        }
+      }
+    }
+
+  }
+
+  [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());
+    public static pb::MessageParser<Void> Parser { get { return _parser; } }
+
+    public static pbr::MessageDescriptor Descriptor {
+      get { return global::Grpc.Testing.ControlReflection.Descriptor.MessageTypes[16]; }
+    }
+
+    pbr::MessageDescriptor pb::IMessage.Descriptor {
+      get { return Descriptor; }
+    }
+
+    public Void() {
+      OnConstruction();
+    }
+
+    partial void OnConstruction();
+
+    public Void(Void other) : this() {
+    }
+
+    public Void Clone() {
+      return new Void(this);
+    }
+
+    public override bool Equals(object other) {
+      return Equals(other as Void);
+    }
+
+    public bool Equals(Void other) {
+      if (ReferenceEquals(other, null)) {
+        return false;
+      }
+      if (ReferenceEquals(other, this)) {
+        return true;
+      }
+      return true;
+    }
+
+    public override int GetHashCode() {
+      int hash = 1;
+      return hash;
+    }
+
+    public override string ToString() {
+      return pb::JsonFormatter.ToDiagnosticString(this);
+    }
+
+    public void WriteTo(pb::CodedOutputStream output) {
+    }
+
+    public int CalculateSize() {
+      int size = 0;
+      return size;
+    }
+
+    public void MergeFrom(Void other) {
+      if (other == null) {
+        return;
+      }
+    }
+
+    public void MergeFrom(pb::CodedInputStream input) {
+      uint tag;
+      while ((tag = input.ReadTag()) != 0) {
+        switch(tag) {
+          default:
+            input.SkipLastField();
+            break;
+        }
+      }
+    }
+
+  }
+
   #endregion
 
 }
diff --git a/src/csharp/Grpc.IntegrationTesting/Histogram.cs b/src/csharp/Grpc.IntegrationTesting/Histogram.cs
index 7e7cb2c..08a674d 100644
--- a/src/csharp/Grpc.IntegrationTesting/Histogram.cs
+++ b/src/csharp/Grpc.IntegrationTesting/Histogram.cs
@@ -1,6 +1,6 @@
 #region Copyright notice and license
 
-// Copyright 2015, Google Inc.
+// Copyright 2015-2016, Google Inc.
 // All rights reserved.
 //
 // Redistribution and use in source and binary forms, with or without
@@ -66,8 +66,8 @@
 
         public Histogram(double resolution, double maxPossible)
         {
-            Grpc.Core.Utils.Preconditions.CheckArgument(resolution > 0);
-            Grpc.Core.Utils.Preconditions.CheckArgument(maxPossible > 0);
+            GrpcPreconditions.CheckArgument(resolution > 0);
+            GrpcPreconditions.CheckArgument(maxPossible > 0);
             this.maxPossible = maxPossible;
             this.multiplier = 1.0 + resolution;
             this.oneOnLogMultiplier = 1.0 / Math.Log(1.0 + resolution);
diff --git a/src/csharp/Grpc.IntegrationTesting/InteropClientServerTest.cs b/src/csharp/Grpc.IntegrationTesting/InteropClientServerTest.cs
index 18168f9..0d12c41 100644
--- a/src/csharp/Grpc.IntegrationTesting/InteropClientServerTest.cs
+++ b/src/csharp/Grpc.IntegrationTesting/InteropClientServerTest.cs
@@ -1,6 +1,6 @@
 #region Copyright notice and license
 
-// Copyright 2015, Google Inc.
+// Copyright 2015-2016, Google Inc.
 // All rights reserved.
 //
 // Redistribution and use in source and binary forms, with or without
@@ -140,14 +140,12 @@
         }
 
         [Test]
-        [Ignore("TODO: see #4427")]
         public async Task StatusCodeAndMessage()
         {
             await InteropClient.RunStatusCodeAndMessageAsync(client);
         }
 
         [Test]
-        [Ignore("TODO: see #4427")]
         public void UnimplementedMethod()
         {
             InteropClient.RunUnimplementedMethod(UnimplementedService.NewClient(channel));
diff --git a/src/csharp/Grpc.IntegrationTesting/QpsWorker.cs b/src/csharp/Grpc.IntegrationTesting/QpsWorker.cs
index 686b484..e407792 100644
--- a/src/csharp/Grpc.IntegrationTesting/QpsWorker.cs
+++ b/src/csharp/Grpc.IntegrationTesting/QpsWorker.cs
@@ -1,6 +1,6 @@
 #region Copyright notice and license
 
-// Copyright 2015, Google Inc.
+// Copyright 2015-2016, Google Inc.
 // All rights reserved.
 //
 // Redistribution and use in source and binary forms, with or without
@@ -85,24 +85,27 @@
             }
 
             var workerServer = new QpsWorker(options);
-            workerServer.Run();
+            workerServer.RunAsync().Wait();
         }
 
-        private void Run()
+        private async Task RunAsync()
         {
             string host = "0.0.0.0";
             int port = options.DriverPort;
 
+            var tcs = new TaskCompletionSource<object>();
+            var workerServiceImpl = new WorkerServiceImpl(() => { Task.Run(() => tcs.SetResult(null)); });
+                
             var server = new Server
             {
-                Services = { WorkerService.BindService(new WorkerServiceImpl()) },
+                Services = { WorkerService.BindService(workerServiceImpl) },
                 Ports = { new ServerPort(host, options.DriverPort, ServerCredentials.Insecure )}
             };
             int boundPort = server.Ports.Single().BoundPort;
             Console.WriteLine("Running qps worker server on " + string.Format("{0}:{1}", host, boundPort));
             server.Start();
-
-            server.ShutdownTask.Wait();
+            await tcs.Task;
+            await server.ShutdownAsync();
         }
     }
 }
diff --git a/src/csharp/Grpc.IntegrationTesting/RunnerClientServerTest.cs b/src/csharp/Grpc.IntegrationTesting/RunnerClientServerTest.cs
index 3dd91b7..06d5ee9 100644
--- a/src/csharp/Grpc.IntegrationTesting/RunnerClientServerTest.cs
+++ b/src/csharp/Grpc.IntegrationTesting/RunnerClientServerTest.cs
@@ -1,6 +1,6 @@
 #region Copyright notice and license
 
-// Copyright 2015, Google Inc.
+// Copyright 2015-2016, Google Inc.
 // All rights reserved.
 //
 // Redistribution and use in source and binary forms, with or without
@@ -48,7 +48,6 @@
     /// </summary>
     public class RunnerClientServerTest
     {
-        const string Host = "localhost";
         IServerRunner serverRunner;
 
         [TestFixtureSetUp]
@@ -57,7 +56,6 @@
             var serverConfig = new ServerConfig
             {
                 ServerType = ServerType.ASYNC_SERVER,
-                Host = Host,
                 PayloadConfig = new PayloadConfig
                 {
                     SimpleParams = new SimpleProtoParams
@@ -83,7 +81,7 @@
         {
             var config = new ClientConfig
             {
-                ServerTargets = { string.Format("{0}:{1}", Host, serverRunner.BoundPort) },
+                ServerTargets = { string.Format("{0}:{1}", "localhost", serverRunner.BoundPort) },
                 RpcType = RpcType.UNARY,
                 LoadParams = new LoadParams { ClosedLoop = new ClosedLoopParams() },
                 PayloadConfig = new PayloadConfig
diff --git a/src/csharp/Grpc.IntegrationTesting/ServerRunners.cs b/src/csharp/Grpc.IntegrationTesting/ServerRunners.cs
index e8be775..4a73645 100644
--- a/src/csharp/Grpc.IntegrationTesting/ServerRunners.cs
+++ b/src/csharp/Grpc.IntegrationTesting/ServerRunners.cs
@@ -1,6 +1,6 @@
 #region Copyright notice and license
 
-// Copyright 2015, Google Inc.
+// Copyright 2015-2016, Google Inc.
 // All rights reserved.
 //
 // Redistribution and use in source and binary forms, with or without
@@ -57,7 +57,7 @@
         /// </summary>
         public static IServerRunner CreateStarted(ServerConfig config)
         {
-            Grpc.Core.Utils.Preconditions.CheckArgument(config.ServerType == ServerType.ASYNC_SERVER);
+            GrpcPreconditions.CheckArgument(config.ServerType == ServerType.ASYNC_SERVER);
             var credentials = config.SecurityParams != null ? TestCredentials.CreateSslServerCredentials() : ServerCredentials.Insecure;
 
             // TODO: qps_driver needs to setup payload properly...
@@ -65,7 +65,7 @@
             var server = new Server
             {
                 Services = { BenchmarkService.BindService(new BenchmarkServiceImpl(responseSize)) },
-                Ports = { new ServerPort(config.Host, config.Port, credentials) }
+                Ports = { new ServerPort("[::]", config.Port, credentials) }
             };
 
             server.Start();
@@ -83,7 +83,7 @@
 
         public ServerRunnerImpl(Server server)
         {
-            this.server = Grpc.Core.Utils.Preconditions.CheckNotNull(server);
+            this.server = GrpcPreconditions.CheckNotNull(server);
         }
 
         public int BoundPort
diff --git a/src/csharp/Grpc.IntegrationTesting/Services.cs b/src/csharp/Grpc.IntegrationTesting/Services.cs
index 04a092c..a8475c1 100644
--- a/src/csharp/Grpc.IntegrationTesting/Services.cs
+++ b/src/csharp/Grpc.IntegrationTesting/Services.cs
@@ -29,11 +29,14 @@
             "QmVuY2htYXJrU2VydmljZRJGCglVbmFyeUNhbGwSGy5ncnBjLnRlc3Rpbmcu",
             "U2ltcGxlUmVxdWVzdBocLmdycGMudGVzdGluZy5TaW1wbGVSZXNwb25zZRJO",
             "Cg1TdHJlYW1pbmdDYWxsEhsuZ3JwYy50ZXN0aW5nLlNpbXBsZVJlcXVlc3Qa",
-            "HC5ncnBjLnRlc3RpbmcuU2ltcGxlUmVzcG9uc2UoATABMp0BCg1Xb3JrZXJT",
+            "HC5ncnBjLnRlc3RpbmcuU2ltcGxlUmVzcG9uc2UoATABMpcCCg1Xb3JrZXJT",
             "ZXJ2aWNlEkUKCVJ1blNlcnZlchIYLmdycGMudGVzdGluZy5TZXJ2ZXJBcmdz",
             "GhouZ3JwYy50ZXN0aW5nLlNlcnZlclN0YXR1cygBMAESRQoJUnVuQ2xpZW50",
             "EhguZ3JwYy50ZXN0aW5nLkNsaWVudEFyZ3MaGi5ncnBjLnRlc3RpbmcuQ2xp",
-            "ZW50U3RhdHVzKAEwAWIGcHJvdG8z"));
+            "ZW50U3RhdHVzKAEwARJCCglDb3JlQ291bnQSGS5ncnBjLnRlc3RpbmcuQ29y",
+            "ZVJlcXVlc3QaGi5ncnBjLnRlc3RpbmcuQ29yZVJlc3BvbnNlEjQKClF1aXRX",
+            "b3JrZXISEi5ncnBjLnRlc3RpbmcuVm9pZBoSLmdycGMudGVzdGluZy5Wb2lk",
+            "YgZwcm90bzM="));
       descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
           new pbr::FileDescriptor[] { global::Grpc.Testing.MessagesReflection.Descriptor, global::Grpc.Testing.ControlReflection.Descriptor, },
           new pbr::GeneratedCodeInfo(null, null));
diff --git a/src/csharp/Grpc.IntegrationTesting/ServicesGrpc.cs b/src/csharp/Grpc.IntegrationTesting/ServicesGrpc.cs
index dd30afb..996439a 100644
--- a/src/csharp/Grpc.IntegrationTesting/ServicesGrpc.cs
+++ b/src/csharp/Grpc.IntegrationTesting/ServicesGrpc.cs
@@ -114,6 +114,9 @@
     static readonly Marshaller<global::Grpc.Testing.ServerStatus> __Marshaller_ServerStatus = Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Testing.ServerStatus.Parser.ParseFrom);
     static readonly Marshaller<global::Grpc.Testing.ClientArgs> __Marshaller_ClientArgs = Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Testing.ClientArgs.Parser.ParseFrom);
     static readonly Marshaller<global::Grpc.Testing.ClientStatus> __Marshaller_ClientStatus = Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Testing.ClientStatus.Parser.ParseFrom);
+    static readonly Marshaller<global::Grpc.Testing.CoreRequest> __Marshaller_CoreRequest = Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Testing.CoreRequest.Parser.ParseFrom);
+    static readonly Marshaller<global::Grpc.Testing.CoreResponse> __Marshaller_CoreResponse = Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Testing.CoreResponse.Parser.ParseFrom);
+    static readonly Marshaller<global::Grpc.Testing.Void> __Marshaller_Void = Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Testing.Void.Parser.ParseFrom);
 
     static readonly Method<global::Grpc.Testing.ServerArgs, global::Grpc.Testing.ServerStatus> __Method_RunServer = new Method<global::Grpc.Testing.ServerArgs, global::Grpc.Testing.ServerStatus>(
         MethodType.DuplexStreaming,
@@ -129,6 +132,20 @@
         __Marshaller_ClientArgs,
         __Marshaller_ClientStatus);
 
+    static readonly Method<global::Grpc.Testing.CoreRequest, global::Grpc.Testing.CoreResponse> __Method_CoreCount = new Method<global::Grpc.Testing.CoreRequest, global::Grpc.Testing.CoreResponse>(
+        MethodType.Unary,
+        __ServiceName,
+        "CoreCount",
+        __Marshaller_CoreRequest,
+        __Marshaller_CoreResponse);
+
+    static readonly Method<global::Grpc.Testing.Void, global::Grpc.Testing.Void> __Method_QuitWorker = new Method<global::Grpc.Testing.Void, global::Grpc.Testing.Void>(
+        MethodType.Unary,
+        __ServiceName,
+        "QuitWorker",
+        __Marshaller_Void,
+        __Marshaller_Void);
+
     // service descriptor
     public static global::Google.Protobuf.Reflection.ServiceDescriptor Descriptor
     {
@@ -142,6 +159,14 @@
       AsyncDuplexStreamingCall<global::Grpc.Testing.ServerArgs, global::Grpc.Testing.ServerStatus> RunServer(CallOptions options);
       AsyncDuplexStreamingCall<global::Grpc.Testing.ClientArgs, global::Grpc.Testing.ClientStatus> RunClient(Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
       AsyncDuplexStreamingCall<global::Grpc.Testing.ClientArgs, global::Grpc.Testing.ClientStatus> RunClient(CallOptions options);
+      global::Grpc.Testing.CoreResponse CoreCount(global::Grpc.Testing.CoreRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
+      global::Grpc.Testing.CoreResponse CoreCount(global::Grpc.Testing.CoreRequest request, CallOptions options);
+      AsyncUnaryCall<global::Grpc.Testing.CoreResponse> CoreCountAsync(global::Grpc.Testing.CoreRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
+      AsyncUnaryCall<global::Grpc.Testing.CoreResponse> CoreCountAsync(global::Grpc.Testing.CoreRequest request, CallOptions options);
+      global::Grpc.Testing.Void QuitWorker(global::Grpc.Testing.Void request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
+      global::Grpc.Testing.Void QuitWorker(global::Grpc.Testing.Void request, CallOptions options);
+      AsyncUnaryCall<global::Grpc.Testing.Void> QuitWorkerAsync(global::Grpc.Testing.Void request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
+      AsyncUnaryCall<global::Grpc.Testing.Void> QuitWorkerAsync(global::Grpc.Testing.Void request, CallOptions options);
     }
 
     // server-side interface
@@ -149,6 +174,8 @@
     {
       Task RunServer(IAsyncStreamReader<global::Grpc.Testing.ServerArgs> requestStream, IServerStreamWriter<global::Grpc.Testing.ServerStatus> responseStream, ServerCallContext context);
       Task RunClient(IAsyncStreamReader<global::Grpc.Testing.ClientArgs> requestStream, IServerStreamWriter<global::Grpc.Testing.ClientStatus> responseStream, ServerCallContext context);
+      Task<global::Grpc.Testing.CoreResponse> CoreCount(global::Grpc.Testing.CoreRequest request, ServerCallContext context);
+      Task<global::Grpc.Testing.Void> QuitWorker(global::Grpc.Testing.Void request, ServerCallContext context);
     }
 
     // client stub
@@ -177,6 +204,46 @@
         var call = CreateCall(__Method_RunClient, options);
         return Calls.AsyncDuplexStreamingCall(call);
       }
+      public global::Grpc.Testing.CoreResponse CoreCount(global::Grpc.Testing.CoreRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+      {
+        var call = CreateCall(__Method_CoreCount, new CallOptions(headers, deadline, cancellationToken));
+        return Calls.BlockingUnaryCall(call, request);
+      }
+      public global::Grpc.Testing.CoreResponse CoreCount(global::Grpc.Testing.CoreRequest request, CallOptions options)
+      {
+        var call = CreateCall(__Method_CoreCount, options);
+        return Calls.BlockingUnaryCall(call, request);
+      }
+      public AsyncUnaryCall<global::Grpc.Testing.CoreResponse> CoreCountAsync(global::Grpc.Testing.CoreRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+      {
+        var call = CreateCall(__Method_CoreCount, new CallOptions(headers, deadline, cancellationToken));
+        return Calls.AsyncUnaryCall(call, request);
+      }
+      public AsyncUnaryCall<global::Grpc.Testing.CoreResponse> CoreCountAsync(global::Grpc.Testing.CoreRequest request, CallOptions options)
+      {
+        var call = CreateCall(__Method_CoreCount, options);
+        return Calls.AsyncUnaryCall(call, request);
+      }
+      public global::Grpc.Testing.Void QuitWorker(global::Grpc.Testing.Void request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+      {
+        var call = CreateCall(__Method_QuitWorker, new CallOptions(headers, deadline, cancellationToken));
+        return Calls.BlockingUnaryCall(call, request);
+      }
+      public global::Grpc.Testing.Void QuitWorker(global::Grpc.Testing.Void request, CallOptions options)
+      {
+        var call = CreateCall(__Method_QuitWorker, options);
+        return Calls.BlockingUnaryCall(call, request);
+      }
+      public AsyncUnaryCall<global::Grpc.Testing.Void> QuitWorkerAsync(global::Grpc.Testing.Void request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+      {
+        var call = CreateCall(__Method_QuitWorker, new CallOptions(headers, deadline, cancellationToken));
+        return Calls.AsyncUnaryCall(call, request);
+      }
+      public AsyncUnaryCall<global::Grpc.Testing.Void> QuitWorkerAsync(global::Grpc.Testing.Void request, CallOptions options)
+      {
+        var call = CreateCall(__Method_QuitWorker, options);
+        return Calls.AsyncUnaryCall(call, request);
+      }
     }
 
     // creates service definition that can be registered with a server
@@ -184,7 +251,9 @@
     {
       return ServerServiceDefinition.CreateBuilder(__ServiceName)
           .AddMethod(__Method_RunServer, serviceImpl.RunServer)
-          .AddMethod(__Method_RunClient, serviceImpl.RunClient).Build();
+          .AddMethod(__Method_RunClient, serviceImpl.RunClient)
+          .AddMethod(__Method_CoreCount, serviceImpl.CoreCount)
+          .AddMethod(__Method_QuitWorker, serviceImpl.QuitWorker).Build();
     }
 
     // creates a new client
diff --git a/src/csharp/Grpc.IntegrationTesting/WorkerServiceImpl.cs b/src/csharp/Grpc.IntegrationTesting/WorkerServiceImpl.cs
index bb2918b..cab299a 100644
--- a/src/csharp/Grpc.IntegrationTesting/WorkerServiceImpl.cs
+++ b/src/csharp/Grpc.IntegrationTesting/WorkerServiceImpl.cs
@@ -1,6 +1,6 @@
 #region Copyright notice and license
 
-// Copyright 2015, Google Inc.
+// Copyright 2015-2016, Google Inc.
 // All rights reserved.
 //
 // Redistribution and use in source and binary forms, with or without
@@ -47,9 +47,16 @@
     /// </summary>
     public class WorkerServiceImpl : WorkerService.IWorkerService
     {
+        readonly Action stopRequestHandler;
+
+        public WorkerServiceImpl(Action stopRequestHandler)
+        {
+            this.stopRequestHandler = GrpcPreconditions.CheckNotNull(stopRequestHandler);
+        }
+        
         public async Task RunServer(IAsyncStreamReader<ServerArgs> requestStream, IServerStreamWriter<ServerStatus> responseStream, ServerCallContext context)
         {
-            Grpc.Core.Utils.Preconditions.CheckState(await requestStream.MoveNext());
+            GrpcPreconditions.CheckState(await requestStream.MoveNext());
             var serverConfig = requestStream.Current.Setup;
             var runner = ServerRunners.CreateStarted(serverConfig);
 
@@ -73,7 +80,7 @@
 
         public async Task RunClient(IAsyncStreamReader<ClientArgs> requestStream, IServerStreamWriter<ClientStatus> responseStream, ServerCallContext context)
         {
-            Grpc.Core.Utils.Preconditions.CheckState(await requestStream.MoveNext());
+            GrpcPreconditions.CheckState(await requestStream.MoveNext());
             var clientConfig = requestStream.Current.Setup;
             var runner = ClientRunners.CreateStarted(clientConfig);
 
@@ -92,5 +99,16 @@
             }
             await runner.StopAsync();
         }
+
+        public Task<CoreResponse> CoreCount(CoreRequest request, ServerCallContext context)
+        {
+            return Task.FromResult(new CoreResponse { Cores = Environment.ProcessorCount });
+        }
+
+        public Task<Void> QuitWorker(Void request, ServerCallContext context)
+        {
+            stopRequestHandler();
+            return Task.FromResult(new Void());
+        }
     }
 }
diff --git a/src/csharp/Grpc.Tools.nuspec b/src/csharp/Grpc.Tools.nuspec
index 48a7b1f..31d1bed 100644
--- a/src/csharp/Grpc.Tools.nuspec
+++ b/src/csharp/Grpc.Tools.nuspec
@@ -4,18 +4,29 @@
     <id>Grpc.Tools</id>
     <title>gRPC C# Tools</title>
     <summary>Tools for C# implementation of gRPC - an RPC library and framework</summary>
-    <description>Precompiled Windows binary for generating gRPC client/server code</description>
+    <description>Precompiled protobuf compiler and gRPC protobuf compiler plugin for generating gRPC client/server C# code. Binaries are available for Windows, Linux and MacOS.</description>
     <version>$version$</version>
     <authors>Google Inc.</authors>
     <owners>grpc-packages</owners>
     <licenseUrl>https://github.com/grpc/grpc/blob/master/LICENSE</licenseUrl>
     <projectUrl>https://github.com/grpc/grpc</projectUrl>
     <requireLicenseAcceptance>false</requireLicenseAcceptance>
-    <releaseNotes>grpc_csharp_plugin.exe - gRPC C# protoc plugin version $version$</releaseNotes>
+    <releaseNotes>Release $version$</releaseNotes>
     <copyright>Copyright 2015, Google Inc.</copyright>
     <tags>gRPC RPC Protocol HTTP/2</tags>
   </metadata>
   <files>
-    <file src="..\..\vsprojects\Release\grpc_csharp_plugin.exe" target="tools" />
+    <file src="protoc_plugins\windows_x86\protoc.exe" target="tools\windows_x86\protoc.exe" />
+    <file src="protoc_plugins\windows_x86\grpc_csharp_plugin.exe" target="tools\windows_x86\grpc_csharp_plugin.exe" />
+    <file src="protoc_plugins\windows_x64\protoc.exe" target="tools\windows_x64\protoc.exe" />
+    <file src="protoc_plugins\windows_x64\grpc_csharp_plugin.exe" target="tools\windows_x64\grpc_csharp_plugin.exe" />
+    <file src="protoc_plugins\linux_x86\protoc" target="tools\linux_x86\protoc" />
+    <file src="protoc_plugins\linux_x86\grpc_csharp_plugin" target="tools\linux_x86\grpc_csharp_plugin" />
+    <file src="protoc_plugins\linux_x64\protoc" target="tools\linux_x64\protoc" />
+    <file src="protoc_plugins\linux_x64\grpc_csharp_plugin" target="tools\linux_x64\grpc_csharp_plugin" />
+    <file src="protoc_plugins\macosx_x86\protoc" target="tools\macosx_x86\protoc" />
+    <file src="protoc_plugins\macosx_x86\grpc_csharp_plugin" target="tools\macosx_x86\grpc_csharp_plugin" />
+    <file src="protoc_plugins\macosx_x64\protoc" target="tools\macosx_x64\protoc" />
+    <file src="protoc_plugins\macosx_x64\grpc_csharp_plugin" target="tools\macosx_x64\grpc_csharp_plugin" />
   </files>
 </package>
diff --git a/src/csharp/README.md b/src/csharp/README.md
index 65ae0b5..b4fa945 100644
--- a/src/csharp/README.md
+++ b/src/csharp/README.md
@@ -12,9 +12,9 @@
 PREREQUISITES
 --------------
 
-- Windows: .NET Framework 4.5+, Visual Studio 2013 or 2015.
-- Linux: Mono 3.2.8+, MonoDevelop 5.9 with NuGet add-in installed.
-- Mac OS X: [homebrew][], Xamarin Studio with NuGet add-in installed.
+- Windows: .NET Framework 4.5+, Visual Studio 2013 or 2015
+- Linux: Mono 4+, MonoDevelop 5.9+ (with NuGet add-in installed)
+- Mac OS X: Xamarin Studio 5.9+
 
 HOW TO USE
 --------------
@@ -24,66 +24,28 @@
 - Open Visual Studio and start a new project/solution.
 
 - Add NuGet package `Grpc` as a dependency (Project options -> Manage NuGet Packages).
-  That will also pull all the transitive dependencies (including the native libraries that
+  That will also pull all the transitive dependencies (including the gRPC native library that
   gRPC C# is using internally).
 
 **Linux (Debian)**
 
-- Add [Debian jessie-backports][] to your `sources.list` file. Example:
-
-  ```sh
-  echo "deb http://http.debian.net/debian jessie-backports main" | \
-  sudo tee -a /etc/apt/sources.list
-  ```
-
-- Install the gRPC Debian package
-
-  ```sh
-  sudo apt-get update
-  sudo apt-get install libgrpc0
-  ```
-
-- gRPC C# depends on native shared library `libgrpc_csharp_ext.so` (Unix flavor of grpc_csharp_ext.dll).
-  This library is not part of the base gRPC debian package and needs to be installed manually from
-  a `.deb` file. Download the debian package `libgrpc_csharp_ext` from corresponding gRPC release on GitHub
-  and install it using `dpkg`.
-
-  ```sh
-  # choose version corresponding to the version of libgrpc you've installed.
-  wget https://github.com/grpc/grpc/releases/download/release-0_11_0/libgrpc-csharp-ext0_0.11.0.0-1_amd64.deb
-  dpkg -i libgrpc-csharp-ext0_0.11.0.0-1_amd64.deb
-  ```
-
 - Open MonoDevelop and start a new project/solution.
 
 - Add NuGet package `Grpc` as a dependency (Project -> Add NuGet packages).
+  That will also pull all the transitive dependencies (including the gRPC native library that
+  gRPC C# is using internally).
 
-- NOTE: Currently, there are no debian packages for the latest version Protocol Buffers compiler (_protoc_)
-  and the gRPC _protoc_ plugin. You can install them using [gRPC Linuxbrew instructions][].
+- NOTE: gRPC C# doesn't have a good story yet for shipping precompiled Linux version of Protocol Buffers compiler (_protoc_) and the gRPC _protoc_ plugin. You can install them using [gRPC Linuxbrew instructions][].
 
 **Mac OS X**
 
-- WARNING: As of now gRPC C# only works on 64bit version of Mono (because we don't compile
-  the native extension for C# in 32bit mode yet). That means your development experience
-  with Xamarin Studio on MacOS will not be great, as you won't be able to run your
-  code directly from Xamarin Studio (which requires 32bit version of Mono).
-
-- Install [homebrew][]. Run the following command to install gRPC C# native dependencies.
-
-  ```sh
-  $ curl -fsSL https://goo.gl/getgrpc | bash -
-  ```
-  This will download and run the [gRPC install script][], then install the latest version of gRPC C core and native C# extension.
-  It also installs Protocol Buffers compiler (_protoc_) and the gRPC _protoc_ plugin for C#.
-
-- Install 64-bit version of mono with command `brew install mono`.
-
 - Open Xamarin Studio and start a new project/solution.
 
 - Add NuGet package `Grpc` as a dependency (Project -> Add NuGet packages).
+  That will also pull all the transitive dependencies (including the gRPC native library that
+  gRPC C# is using internally).
 
-- *You will be able to build your project in Xamarin Studio, but to run or test it,
-  you will need to run it under 64-bit version of Mono.*
+- NOTE: gRPC C# doesn't have a good story yet for shipping precompiled Mac OS X version of Protocol Buffers compiler (_protoc_) and the gRPC _protoc_ plugin. You can install them using [gRPC Homebrew instructions][].
 
 BUILD FROM SOURCE
 -----------------
@@ -94,7 +56,7 @@
 **Windows**
 
 - The grpc_csharp_ext native library needs to be built so you can build the gRPC C# solution. You can 
-  either build the native solution in `vsprojects/grpc.sln` from Visual Studio manually, or you can use
+  either build the native solution in `vsprojects/grpc_csharp_ext.sln` from Visual Studio manually, or you can use
   a convenience batch script that builds everything for you.
 
   ```
@@ -102,30 +64,28 @@
   > buildall.bat
   ```
 
-- Open Grpc.sln using Visual Studio. NuGet dependencies will be restored
-  upon build (you need to have NuGet add-in installed).
+- Open Grpc.sln using Visual Studio.
 
 **Linux**
 
+- The grpc_csharp_ext native library needs to be built so you can build the gRPC C# solution:
   ```sh
-  $ sudo apt-get install mono-devel
-  $ sudo apt-get install nunit nunit-console
-  ```
-
-You can use older versions of MonoDevelop, but then you might need to restore
-NuGet dependencies manually (by `nuget restore`), because older versions of MonoDevelop
-don't support NuGet add-in.
-
-- Compile and install the gRPC C# extension library (that will be used via
-  P/Invoke from C#).
-  ```sh
-  $ make grpc_csharp_ext
-  $ sudo make install_grpc_csharp_ext
+  # from the gRPC repository root
+  $ make CONFIG=dbg grpc_csharp_ext
   ```
 
 - Use MonoDevelop to open the solution Grpc.sln
 
-- Build the solution & run all the tests from test view.
+**Mac OS X**
+
+- The grpc_csharp_ext native library needs to be built so you can build the gRPC C# solution.
+  
+  ```sh
+  # from the gRPC repository root
+  $ tools/run_tests/run_tests.py -c dbg -l csharp --build_only
+  ```
+
+- Use Xamarin Studio to open the solution Grpc.sln
 
 RUNNING TESTS
 -------------
@@ -135,17 +95,9 @@
 Under Visual Studio, make sure NUnit test adapter is installed (under "Extensions and Updates").
 Then you should be able to run all the tests using Test Explorer.
 
-Under Monodevelop, make sure you installed "NUnit support" in Add-in manager.
+Under Monodevelop or Xamarin Studio, make sure you installed "NUnit support" in Add-in manager.
 Then you should be able to run all the test from the Test View.
 
-After building the solution, you can also run the tests from command line 
-using nunit-console tool.
-
-```sh
-# from Grpc.Core.Test/bin/Debug directory
-$ nunit-console Grpc.Core.Tests.dll
-```
-
 gRPC team uses a Python script to simplify facilitate running tests for
 different languages.
 
@@ -176,27 +128,15 @@
 - Grpc.IntegrationTesting:
   Cross-language gRPC implementation testing (interop testing).
 
-TROUBLESHOOTING
+THE NATIVE DEPENDENCY
 ---------------
 
-### Problem: Unable to load DLL 'grpc_csharp_ext.dll'
+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.
 
-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. If you get the above error, it means that the native dependencies could not be located by the C# runtime (or they are incompatible with the current runtime, so they could not be loaded). The solution to this is environment specific.
-
-- If you are developing on Windows in Visual Studio, the `grpc_csharp_ext.dll` that is shipped by gRPC nuget packages should be automatically copied to your build destination folder once you build. By adjusting project properties in your VS project file, you can influence which exact configuration of `grpc_csharp_ext.dll` will be used (based on VS version, bitness, debug/release configuration).
-
-- If you are running your application that is using gRPC on Windows machine that doesn't have Visual Studio installed, you might need to install [Visual C++ 2013 redistributable](https://www.microsoft.com/en-us/download/details.aspx?id=40784) that contains some system .dll libraries that `grpc_csharp_ext.dll` depends on (see #905 for more details).
-
-- On Linux (or Docker), you need to first install gRPC C core and `libgrpc_csharp_ext.so` shared libraries.
-  See [How to Use](#how-to-use) section for details how to install it.
-  Installation on a machine where your application is going to be deployed is no different.
-
-- On Mac, you need to first install gRPC C core and `libgrpc_csharp_ext.dylib` shared libraries using Homebrew. See above for installation instruction.
-  Installation on a machine where your application is going to be deployed is no different.
-
-- Possible cause for the problem is that the `grpc_csharp_ext` library is installed, but it has different bitness (32/64bit) than your C# runtime (in case you are using mono) or C# application.
+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).
 
 [gRPC Linuxbrew instructions]:https://github.com/grpc/homebrew-grpc#quick-install-linux
+[gRPC Homebrew instructions]:https://github.com/grpc/homebrew-grpc#quick-install-linux
 [homebrew]:http://brew.sh
 [gRPC install script]:https://raw.githubusercontent.com/grpc/homebrew-grpc/master/scripts/install
 [grpc.io]: http://www.grpc.io/docs/installation/csharp.html
diff --git a/src/csharp/build_packages.bat b/src/csharp/build_packages.bat
index b7768f7..7c42a6d 100644
--- a/src/csharp/build_packages.bat
+++ b/src/csharp/build_packages.bat
@@ -19,6 +19,14 @@
 xcopy /Y /I ..\..\architecture=x86,language=csharp,platform=macos\artifacts\* grpc.native.csharp\macosx_x86\
 xcopy /Y /I ..\..\architecture=x64,language=csharp,platform=macos\artifacts\* grpc.native.csharp\macosx_x64\
 
+@rem Collect protoc artifacts built by the previous build step
+xcopy /Y /I ..\..\architecture=x86,language=protoc,platform=windows\artifacts\* protoc_plugins\windows_x86\
+xcopy /Y /I ..\..\architecture=x64,language=protoc,platform=windows\artifacts\* protoc_plugins\windows_x64\
+xcopy /Y /I ..\..\architecture=x86,language=protoc,platform=linux\artifacts\* protoc_plugins\linux_x86\
+xcopy /Y /I ..\..\architecture=x64,language=protoc,platform=linux\artifacts\* protoc_plugins\linux_x64\
+xcopy /Y /I ..\..\architecture=x86,language=protoc,platform=macos\artifacts\* protoc_plugins\macosx_x86\
+xcopy /Y /I ..\..\architecture=x64,language=protoc,platform=macos\artifacts\* protoc_plugins\macosx_x64\
+
 @rem Fetch all dependencies
 %NUGET% restore ..\..\vsprojects\grpc_csharp_ext.sln || goto :error
 %NUGET% restore Grpc.sln || goto :error
@@ -27,24 +35,19 @@
 
 @call "%VS120COMNTOOLS%\..\..\vc\vcvarsall.bat" x86
 
-@rem We won't use the native libraries from this step, but without this Grpc.sln will fail.  
+@rem We won't use the native libraries from this step, but without this Grpc.sln will fail.
 msbuild ..\..\vsprojects\grpc_csharp_ext.sln /p:Configuration=Release /p:PlatformToolset=v120 || goto :error
 
 msbuild Grpc.sln /p:Configuration=ReleaseSigned || goto :error
 
 endlocal
 
-@rem TODO(jtattermusch): re-enable protoc plugin building
-@rem @call ..\..\vsprojects\build_plugins.bat || goto :error
-
 %NUGET% pack grpc.native.csharp\grpc.native.csharp.nuspec -Version %VERSION% || goto :error
 %NUGET% pack Grpc.Auth\Grpc.Auth.nuspec -Symbols -Version %VERSION% || goto :error
 %NUGET% pack Grpc.Core\Grpc.Core.nuspec -Symbols -Version %VERSION% || goto :error
 %NUGET% pack Grpc.HealthCheck\Grpc.HealthCheck.nuspec -Symbols -Version %VERSION_WITH_BETA% -Properties ProtobufVersion=%PROTOBUF_VERSION% || goto :error
 %NUGET% pack Grpc.nuspec -Version %VERSION% || goto :error
-
-@rem TODO(jtattermusch): re-enable building Grpc.Tools package
-@rem %NUGET% pack Grpc.Tools.nuspec -Version %VERSION% || goto :error
+%NUGET% pack Grpc.Tools.nuspec -Version %VERSION% || goto :error
 
 @rem copy resulting nuget packages to artifacts directory
 xcopy /Y /I *.nupkg ..\..\artifacts\
diff --git a/src/csharp/generate_proto_csharp.sh b/src/csharp/generate_proto_csharp.sh
index 0261a45..23e0540 100755
--- a/src/csharp/generate_proto_csharp.sh
+++ b/src/csharp/generate_proto_csharp.sh
@@ -42,7 +42,7 @@
     -I src/proto/math src/proto/math/math.proto
 
 $PROTOC --plugin=$PLUGIN --csharp_out=$HEALTHCHECK_DIR --grpc_out=$HEALTHCHECK_DIR \
-    -I src/proto/grpc/health/v1alpha src/proto/grpc/health/v1alpha/health.proto
+    -I src/proto/grpc/health/v1 src/proto/grpc/health/v1/health.proto
 
 $PROTOC --plugin=$PLUGIN --csharp_out=$TESTING_DIR --grpc_out=$TESTING_DIR \
     -I . src/proto/grpc/testing/{control,empty,messages,payloads,services,stats,test}.proto 
diff --git a/src/node/ext/call_credentials.cc b/src/node/ext/call_credentials.cc
index 91acb86..98696db 100644
--- a/src/node/ext/call_credentials.cc
+++ b/src/node/ext/call_credentials.cc
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -187,7 +187,8 @@
   shared_ptr<Resources> resources(new Resources);
   grpc_status_code code = static_cast<grpc_status_code>(
       Nan::To<uint32_t>(info[0]).FromJust());
-  char *details = *Utf8String(info[1]);
+  Utf8String details_utf8_str(info[1]);
+  char *details = *details_utf8_str;
   grpc_metadata_array array;
   if (!CreateMetadataArray(Nan::To<Object>(info[2]).ToLocalChecked(),
                            &array, resources)){
diff --git a/src/node/ext/node_grpc.cc b/src/node/ext/node_grpc.cc
index 654c5ae..0c71b2d 100644
--- a/src/node/ext/node_grpc.cc
+++ b/src/node/ext/node_grpc.cc
@@ -237,7 +237,8 @@
         "headerKeyIsLegal's argument must be a string");
   }
   Local<String> key = Nan::To<String>(info[0]).ToLocalChecked();
-  char *key_str = *Nan::Utf8String(key);
+  Nan::Utf8String key_utf8_str(key);
+  char *key_str = *key_utf8_str;
   info.GetReturnValue().Set(static_cast<bool>(
       grpc_header_key_is_legal(key_str, static_cast<size_t>(key->Length()))));
 }
@@ -248,7 +249,8 @@
         "metadataNonbinValueIsLegal's argument must be a string");
   }
   Local<String> value = Nan::To<String>(info[0]).ToLocalChecked();
-  char *value_str = *Nan::Utf8String(value);
+  Nan::Utf8String value_utf8_str(value);
+  char *value_str = *value_utf8_str;
   info.GetReturnValue().Set(static_cast<bool>(
       grpc_header_nonbin_value_is_legal(
           value_str, static_cast<size_t>(value->Length()))));
@@ -260,7 +262,8 @@
         "metadataKeyIsLegal's argument must be a string");
   }
   Local<String> key = Nan::To<String>(info[0]).ToLocalChecked();
-  char *key_str = *Nan::Utf8String(key);
+  Nan::Utf8String key_utf8_str(key);
+  char *key_str = *key_utf8_str;
   info.GetReturnValue().Set(static_cast<bool>(
       grpc_is_binary_header(key_str, static_cast<size_t>(key->Length()))));
 }
diff --git a/src/node/health_check/health.js b/src/node/health_check/health.js
index 1a2c036..6ab4157 100644
--- a/src/node/health_check/health.js
+++ b/src/node/health_check/health.js
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -38,9 +38,9 @@
 var _ = require('lodash');
 
 var health_proto = grpc.load(__dirname +
-    '/../../proto/grpc/health/v1alpha/health.proto');
+    '/../../proto/grpc/health/v1/health.proto');
 
-var HealthClient = health_proto.grpc.health.v1alpha.Health;
+var HealthClient = health_proto.grpc.health.v1.Health;
 
 function HealthImplementation(statusMap) {
   this.statusMap = _.clone(statusMap);
diff --git a/src/node/src/client.js b/src/node/src/client.js
index c02c447..c65dd73 100644
--- a/src/node/src/client.js
+++ b/src/node/src/client.js
@@ -648,8 +648,8 @@
     var deserialize = attrs.responseDeserialize;
     Client.prototype[name] = requester_makers[method_type](
         attrs.path, serialize, deserialize);
-    Client.prototype[name].serialize = serialize;
-    Client.prototype[name].deserialize = deserialize;
+    // Associate all provided attributes with the method
+    _.assign(Client.prototype[name], attrs);
   });
 
   return Client;
diff --git a/src/node/src/common.js b/src/node/src/common.js
index e521760..7705a27 100644
--- a/src/node/src/common.js
+++ b/src/node/src/common.js
@@ -146,6 +146,8 @@
       path: prefix + method.name,
       requestStream: method.requestStream,
       responseStream: method.responseStream,
+      requestType: method.resolvedRequestType,
+      responseType: method.resolvedResponseType,
       requestSerialize: serializeCls(method.resolvedRequestType.build()),
       requestDeserialize: deserializeCls(method.resolvedRequestType.build(),
                                      binaryAsBase64, longsAsStrings),
diff --git a/src/node/src/credentials.js b/src/node/src/credentials.js
index 710ab6d..1d73723 100644
--- a/src/node/src/credentials.js
+++ b/src/node/src/credentials.js
@@ -98,6 +98,8 @@
         message = error.message;
         if (error.hasOwnProperty('code')) {
           code = error.code;
+        } else {
+          code = grpc.status.UNAUTHENTICATED;
         }
         if (!metadata) {
           metadata = new Metadata();
@@ -116,13 +118,16 @@
 exports.createFromGoogleCredential = function(google_credential) {
   return exports.createFromMetadataGenerator(function(auth_context, callback) {
     var service_url = auth_context.service_url;
+    console.log('Service URL:', service_url);
     google_credential.getRequestMetadata(service_url, function(err, header) {
       if (err) {
+        console.log('Auth error:', err);
         callback(err);
         return;
       }
       var metadata = new Metadata();
       metadata.add('authorization', header.Authorization);
+      console.log(header.Authorization);
       callback(null, metadata);
     });
   });
diff --git a/src/node/src/metadata.js b/src/node/src/metadata.js
index 51a9f8a..33d7ea1 100644
--- a/src/node/src/metadata.js
+++ b/src/node/src/metadata.js
@@ -64,7 +64,7 @@
   if (grpc.metadataKeyIsLegal(key)) {
     return key;
   } else {
-    throw new Error('Metadata key contains illegal characters');
+    throw new Error('Metadata key"' + key + '" contains illegal characters');
   }
 }
 
@@ -79,7 +79,8 @@
           'keys that don\'t end with \'-bin\' must have String values');
     }
     if (!grpc.metadataNonbinValueIsLegal(value)) {
-      throw new Error('Metadata string value contains illegal characters');
+      throw new Error('Metadata string value "' + value +
+                      '" contains illegal characters');
     }
   }
 }
diff --git a/src/objective-c/tests/GRPCClientTests.m b/src/objective-c/tests/GRPCClientTests.m
index 00c4b88..624958f 100644
--- a/src/objective-c/tests/GRPCClientTests.m
+++ b/src/objective-c/tests/GRPCClientTests.m
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -35,6 +35,7 @@
 #import <XCTest/XCTest.h>
 
 #import <GRPCClient/GRPCCall.h>
+#import <GRPCClient/GRPCCall+ChannelArg.h>
 #import <GRPCClient/GRPCCall+OAuth2.h>
 #import <GRPCClient/GRPCCall+Tests.h>
 #import <ProtoRPC/ProtoMethod.h>
@@ -45,6 +46,7 @@
 static NSString * const kHostAddress = @"localhost:5050";
 static NSString * const kPackage = @"grpc.testing";
 static NSString * const kService = @"TestService";
+static NSString * const kRemoteSSLHost = @"grpc-test.sandbox.googleapis.com";
 
 static ProtoMethod *kInexistentMethod;
 static ProtoMethod *kEmptyCallMethod;
@@ -101,6 +103,8 @@
 @implementation GRPCClientTests
 
 - (void)setUp {
+  // Add a custom user agent prefix that will be used in test
+  [GRPCCall setUserAgentPrefix:@"Foo" forHost:kHostAddress];
   // Register test server as non-SSL.
   [GRPCCall useInsecureConnectionsForHost:kHostAddress];
 
@@ -127,8 +131,7 @@
     XCTFail(@"Received unexpected response: %@", value);
   } completionHandler:^(NSError *errorOrNil) {
     XCTAssertNotNil(errorOrNil, @"Finished without error!");
-    // TODO(jcanizales): The server should return code 12 UNIMPLEMENTED, not 5 NOT FOUND.
-    XCTAssertEqual(errorOrNil.code, 5, @"Finished with unexpected error: %@", errorOrNil);
+    XCTAssertEqual(errorOrNil.code, 12, @"Finished with unexpected error: %@", errorOrNil);
     [expectation fulfill];
   }];
 
@@ -191,7 +194,6 @@
   [self waitForExpectationsWithTimeout:8 handler:nil];
 }
 
-// TODO(jcanizales): Activate this test against the remote server.
 - (void)testMetadata {
   __weak XCTestExpectation *expectation = [self expectationWithDescription:@"RPC unauthorized."];
 
@@ -200,7 +202,7 @@
   request.fillOauthScope = YES;
   GRXWriter *requestsWriter = [GRXWriter writerWithValue:[request data]];
 
-  GRPCCall *call = [[GRPCCall alloc] initWithHost:kHostAddress
+  GRPCCall *call = [[GRPCCall alloc] initWithHost:kRemoteSSLHost
                                              path:kUnaryCallMethod.HTTPPath
                                    requestsWriter:requestsWriter];
 
@@ -257,4 +259,69 @@
   [self waitForExpectationsWithTimeout:8 handler:nil];
 }
 
+- (void)testUserAgentPrefix {
+  __weak XCTestExpectation *response = [self expectationWithDescription:@"Empty response received."];
+  __weak XCTestExpectation *completion = [self expectationWithDescription:@"Empty RPC completed."];
+
+  GRPCCall *call = [[GRPCCall alloc] initWithHost:kHostAddress
+                                             path:kEmptyCallMethod.HTTPPath
+                                   requestsWriter:[GRXWriter writerWithValue:[NSData data]]];
+  // Setting this special key in the header will cause the interop server to echo back the
+  // user-agent value, which we confirm.
+  call.requestHeaders[@"x-grpc-test-echo-useragent"] = @"";
+
+  id<GRXWriteable> responsesWriteable = [[GRXWriteable alloc] initWithValueHandler:^(NSData *value) {
+    XCTAssertNotNil(value, @"nil value received as response.");
+    XCTAssertEqual([value length], 0, @"Non-empty response received: %@", value);
+    XCTAssertEqualObjects(call.responseHeaders[@"x-grpc-test-echo-useragent"],
+                          @"Foo grpc-objc/0.13.0 grpc-c/0.14.0-dev (ios)",
+                          @"Did not receive expected user agent %@",
+                          call.responseHeaders[@"x-grpc-test-echo-useragent"]);
+    [response fulfill];
+  } completionHandler:^(NSError *errorOrNil) {
+    XCTAssertNil(errorOrNil, @"Finished with unexpected error: %@", errorOrNil);
+    [completion fulfill];
+  }];
+
+  [call startWithWriteable:responsesWriteable];
+
+  [self waitForExpectationsWithTimeout:8 handler:nil];
+}
+
+// TODO(makarandd): Move to a different file that contains only unit tests
+- (void)testExceptions {
+  // Try to set userAgentPrefix for host that is nil. This should cause
+  // an exception.
+  @try {
+    [GRPCCall setUserAgentPrefix:@"Foo" forHost:nil];
+    XCTFail(@"Did not receive an exception when host is nil");
+  } @catch(NSException *theException) {
+    NSLog(@"Received exception as expected: %@", theException.name);
+  }
+
+  // Try to set parameters to nil for GRPCCall. This should cause an exception
+  @try {
+    GRPCCall *call = [[GRPCCall alloc] initWithHost:nil
+                                               path:nil
+                                     requestsWriter:nil];
+    XCTFail(@"Did not receive an exception when parameters are nil");
+  } @catch(NSException *theException) {
+    NSLog(@"Received exception as expected: %@", theException.name);
+  }
+
+
+  // Set state to Finished by force
+  GRXWriter *requestsWriter = [GRXWriter emptyWriter];
+  [requestsWriter finishWithError:nil];
+  @try {
+    GRPCCall *call = [[GRPCCall alloc] initWithHost:kHostAddress
+                                               path:kUnaryCallMethod.HTTPPath
+                                     requestsWriter:requestsWriter];
+    XCTFail(@"Did not receive an exception when GRXWriter has incorrect state.");
+  } @catch(NSException *theException) {
+    NSLog(@"Received exception as expected: %@", theException.name);
+  }
+
+}
+
 @end
diff --git a/src/objective-c/tests/InteropTestsLocalSSL.m b/src/objective-c/tests/InteropTestsLocalSSL.m
index 9d7afef..155e334 100644
--- a/src/objective-c/tests/InteropTestsLocalSSL.m
+++ b/src/objective-c/tests/InteropTestsLocalSSL.m
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -57,4 +57,15 @@
   [super setUp];
 }
 
+- (void)testExceptions {
+  // Try to set userAgentPrefix for host that is nil. This should cause
+  // an exception.
+  @try {
+    [GRPCCall useTestCertsPath:nil testName:nil forHost:nil];
+    XCTFail(@"Did not receive an exception when parameters are nil");
+  } @catch(NSException *theException) {
+    NSLog(@"Received exception as expected: %@", theException.name);
+  }
+}
+
 @end
diff --git a/src/objective-c/tests/RxLibraryUnitTests.m b/src/objective-c/tests/RxLibraryUnitTests.m
index a67a4c6..d342662 100644
--- a/src/objective-c/tests/RxLibraryUnitTests.m
+++ b/src/objective-c/tests/RxLibraryUnitTests.m
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -137,4 +137,24 @@
   XCTAssertEqualObjects(handler.errorOrNil, anyError);
 }
 
+- (void)testBufferedPipeFinishWriteWhilePaused {
+  // Given:
+  CapturingSingleValueHandler *handler = [CapturingSingleValueHandler handler];
+  id<GRXWriteable> writeable = [GRXWriteable writeableWithSingleHandler:handler.block];
+  id anyValue = @7;
+
+  // If:
+  GRXBufferedPipe *pipe = [GRXBufferedPipe pipe];
+  // Write something, then finish
+  [pipe writeValue:anyValue];
+  [pipe writesFinishedWithError:nil];
+  // then start the writeable
+  [pipe startWithWriteable:writeable];
+
+  // Then:
+  XCTAssertEqual(handler.timesCalled, 1);
+  XCTAssertEqualObjects(handler.value, anyValue);
+  XCTAssertEqualObjects(handler.errorOrNil, nil);
+}
+
 @end
diff --git a/src/php/README.md b/src/php/README.md
index b1823b9..b368482 100644
--- a/src/php/README.md
+++ b/src/php/README.md
@@ -33,45 +33,12 @@
 
 ## Quick Install
 
-**Linux (Debian):**
-
-Add [Debian jessie-backports][] to your `sources.list` file. Example:
-
-```sh
-echo "deb http://http.debian.net/debian jessie-backports main" | \
-sudo tee -a /etc/apt/sources.list
-```
-
-Install the gRPC Debian package
-
-```sh
-sudo apt-get update
-sudo apt-get install libgrpc-dev
-```
-
 Install the gRPC PHP extension
 
 ```sh
 sudo pecl install grpc-beta
 ```
 
-**Mac OS X:**
-
-Install [homebrew][]. Example:
-
-```sh
-ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
-```
-
-Install the gRPC core library and the PHP extension in one step
-
-```sh
-$ curl -fsSL https://goo.gl/getgrpc | bash -s php
-```
-
-This will download and run the [gRPC install script][] and compile the gRPC PHP extension.
-
-
 ## Build from Source
 
 Clone this repository
@@ -297,7 +264,4 @@
 $ curl localhost/math_client.php
 ```
 
-[homebrew]:http://brew.sh
-[gRPC install script]:https://raw.githubusercontent.com/grpc/homebrew-grpc/master/scripts/install
 [Node]:https://github.com/grpc/grpc/tree/master/src/node/examples
-[Debian jessie-backports]:http://backports.debian.org/Instructions/
diff --git a/src/python/grpcio_health_checking/grpc/health/v1alpha/health.proto b/src/proto/grpc/health/v1/health.proto
similarity index 94%
copy from src/python/grpcio_health_checking/grpc/health/v1alpha/health.proto
copy to src/proto/grpc/health/v1/health.proto
index 57f4aaa..6e27606 100644
--- a/src/python/grpcio_health_checking/grpc/health/v1alpha/health.proto
+++ b/src/proto/grpc/health/v1/health.proto
@@ -1,4 +1,4 @@
-// Copyright 2015, Google Inc.
+// Copyright 2015-2016, Google Inc.
 // All rights reserved.
 //
 // Redistribution and use in source and binary forms, with or without
@@ -29,7 +29,8 @@
 
 syntax = "proto3";
 
-package grpc.health.v1alpha;
+package grpc.health.v1;
+option csharp_namespace = "Grpc.Health.V1";
 
 message HealthCheckRequest {
   string service = 1;
diff --git a/src/proto/grpc/health/v1alpha/health.proto b/src/proto/grpc/health/v1alpha/health.proto
deleted file mode 100644
index 05f837d..0000000
--- a/src/proto/grpc/health/v1alpha/health.proto
+++ /dev/null
@@ -1,51 +0,0 @@
-// Copyright 2015-2016, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-syntax = "proto3";
-
-package grpc.health.v1alpha;
-option csharp_namespace = "Grpc.Health.V1Alpha";
-
-message HealthCheckRequest {
-  string host = 1;
-  string service = 2;
-}
-
-message HealthCheckResponse {
-  enum ServingStatus {
-    UNKNOWN = 0;
-    SERVING = 1;
-    NOT_SERVING = 2;
-  }
-  ServingStatus status = 1;
-}
-
-service Health {
-  rpc Check(HealthCheckRequest) returns (HealthCheckResponse);
-}
diff --git a/src/proto/grpc/lb/v0/load_balancer.options b/src/proto/grpc/lb/v0/load_balancer.options
new file mode 100644
index 0000000..6d4528f
--- /dev/null
+++ b/src/proto/grpc/lb/v0/load_balancer.options
@@ -0,0 +1,6 @@
+grpc.lb.v0.InitialLoadBalanceRequest.name max_size:128
+grpc.lb.v0.InitialLoadBalanceResponse.client_config max_size:64
+grpc.lb.v0.InitialLoadBalanceResponse.load_balancer_delegate max_size:64
+grpc.lb.v0.Server.ip_address max_size:46
+grpc.lb.v0.Server.load_balance_token max_size:64
+load_balancer.proto no_unions:true
diff --git a/src/proto/grpc/lb/v0/load_balancer.proto b/src/proto/grpc/lb/v0/load_balancer.proto
new file mode 100644
index 0000000..e88a4f8
--- /dev/null
+++ b/src/proto/grpc/lb/v0/load_balancer.proto
@@ -0,0 +1,144 @@
+// Copyright 2016, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+syntax = "proto3";
+
+package grpc.lb.v0;
+
+message Duration {
+
+  // Signed seconds of the span of time. Must be from -315,576,000,000
+  // to +315,576,000,000 inclusive.
+  int64 seconds = 1;
+
+  // Signed fractions of a second at nanosecond resolution of the span
+  // of time. Durations less than one second are represented with a 0
+  // `seconds` field and a positive or negative `nanos` field. For durations
+  // of one second or more, a non-zero value for the `nanos` field must be
+  // of the same sign as the `seconds` field. Must be from -999,999,999
+  // to +999,999,999 inclusive.
+  int32 nanos = 2;
+}
+
+service LoadBalancer {
+  // Bidirectional rpc to get a list of servers.
+  rpc BalanceLoad(stream LoadBalanceRequest)
+      returns (stream LoadBalanceResponse);
+}
+
+message LoadBalanceRequest {
+  oneof load_balance_request_type {
+    // This message should be sent on the first request to the load balancer.
+    InitialLoadBalanceRequest initial_request = 1;
+
+    // The client stats should be periodically reported to the load balancer
+    // based on the duration defined in the InitialLoadBalanceResponse.
+    ClientStats client_stats = 2;
+  }
+}
+
+message InitialLoadBalanceRequest {
+  // Name of load balanced service (IE, service.grpc.gslb.google.com)
+  string name = 1;
+}
+
+// Contains client level statistics that are useful to load balancing. Each
+// count should be reset to zero after reporting the stats.
+message ClientStats {
+  // The total number of requests sent by the client since the last report.
+  int64 total_requests = 1;
+
+  // The number of client rpc errors since the last report.
+  int64 client_rpc_errors = 2;
+
+  // The number of dropped requests since the last report.
+  int64 dropped_requests = 3;
+}
+
+message LoadBalanceResponse {
+  oneof load_balance_response_type {
+    // This message should be sent on the first response to the client.
+    InitialLoadBalanceResponse initial_response = 1;
+
+    // Contains the list of servers selected by the load balancer. The client
+    // should send requests to these servers in the specified order.
+    ServerList server_list = 2;
+  }
+}
+
+message InitialLoadBalanceResponse {
+  oneof initial_response_type {
+    // Contains gRPC config options like RPC deadline or flow control.
+    // TODO(yetianx): Change to ClientConfig after it is defined.
+    string client_config = 1;
+
+    // This is an application layer redirect that indicates the client should
+    // use the specified server for load balancing. When this field is set in
+    // the response, the client should open a separate connection to the
+    // load_balancer_delegate and call the BalanceLoad method.
+    string load_balancer_delegate = 2;
+  }
+
+  // This interval defines how often the client should send the client stats
+  // to the load balancer. Stats should only be reported when the duration is
+  // positive.
+  Duration client_stats_report_interval = 3;
+}
+
+message ServerList {
+  // Contains a list of servers selected by the load balancer. The list will
+  // be updated when server resolutions change or as needed to balance load
+  // across more servers. The client should consume the server list in order
+  // unless instructed otherwise via the client_config.
+  repeated Server servers = 1;
+
+  // Indicates the amount of time that the client should consider this server
+  // list as valid. It may be considered stale after waiting this interval of
+  // time after receiving the list. If the interval is not positive, the
+  // client can assume the list is valid until the next list is received.
+  Duration expiration_interval = 3;
+}
+
+message Server {
+  // A resolved address and port for the server. The IP address string may
+  // either be an IPv4 or IPv6 address.
+  string ip_address = 1;
+  int32 port = 2;
+
+  // An opaque token that is passed from the client to the server in metadata.
+  // The server may expect this token to indicate that the request from the
+  // client was load balanced.
+  // TODO(yetianx): Not used right now, and will be used after implementing
+  // load report.
+  bytes load_balance_token = 3;
+
+  // Indicates whether this particular request should be dropped by the client
+  // when this server is chosen from the list.
+  bool drop_request = 4;
+}
diff --git a/src/python/grpcio/README.rst b/src/python/grpcio/README.rst
index 698c760..f3e962c 100644
--- a/src/python/grpcio/README.rst
+++ b/src/python/grpcio/README.rst
@@ -38,3 +38,17 @@
 
 Note that `$REPO_ROOT` can be assigned to whatever directory name floats your
 fancy.
+
+Troubleshooting
+~~~~~~~~~~~~~~~
+
+Help, I ...
+
+* **... see a** :code:`pkg_resources.VersionConflict` **when I try to install
+  grpc!**
+
+  This is likely because :code:`pip` doesn't own the offending dependency,
+  which in turn is likely because your operating system's package manager owns
+  it. You'll need to force the installation of the dependency:
+
+  :code:`pip install --ignore-installed $OFFENDING_DEPENDENCY`
diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/channel.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/channel.pyx.pxi
index ac67f32..1f1833d 100644
--- a/src/python/grpcio/grpc/_cython/_cygrpc/channel.pyx.pxi
+++ b/src/python/grpcio/grpc/_cython/_cygrpc/channel.pyx.pxi
@@ -1,4 +1,4 @@
-# Copyright 2015, Google Inc.
+# Copyright 2015-2016, Google Inc.
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
@@ -89,12 +89,13 @@
 
   def check_connectivity_state(self, bint try_to_connect):
     return grpc_channel_check_connectivity_state(self.c_channel,
-                                                      try_to_connect)
+                                                 try_to_connect)
 
   def watch_connectivity_state(
-      self, last_observed_state, Timespec deadline not None,
-      CompletionQueue queue not None, tag):
+      self, grpc_connectivity_state last_observed_state,
+      Timespec deadline not None, CompletionQueue queue not None, tag):
     cdef OperationTag operation_tag = OperationTag(tag)
+    operation_tag.references = [self, queue]
     cpython.Py_INCREF(operation_tag)
     grpc_channel_watch_connectivity_state(
         self.c_channel, last_observed_state, deadline.c_time,
diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/completion_queue.pxd.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/completion_queue.pxd.pxi
index 757f124..305475c 100644
--- a/src/python/grpcio/grpc/_cython/_cygrpc/completion_queue.pxd.pxi
+++ b/src/python/grpcio/grpc/_cython/_cygrpc/completion_queue.pxd.pxi
@@ -1,4 +1,4 @@
-# Copyright 2015, Google Inc.
+# Copyright 2015-2016, Google Inc.
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
@@ -31,8 +31,9 @@
 cdef class CompletionQueue:
 
   cdef grpc_completion_queue *c_completion_queue
-  cdef object poll_condition
-  cdef bint is_polling
+  cdef object pluck_condition
+  cdef int num_plucking
+  cdef int num_polling
   cdef bint is_shutting_down
   cdef bint is_shutdown
 
diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/completion_queue.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/completion_queue.pyx.pxi
index bbf8413..c139147 100644
--- a/src/python/grpcio/grpc/_cython/_cygrpc/completion_queue.pyx.pxi
+++ b/src/python/grpcio/grpc/_cython/_cygrpc/completion_queue.pyx.pxi
@@ -1,4 +1,4 @@
-# Copyright 2015, Google Inc.
+# Copyright 2015-2016, Google Inc.
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
@@ -39,8 +39,9 @@
     self.c_completion_queue = grpc_completion_queue_create(NULL)
     self.is_shutting_down = False
     self.is_shutdown = False
-    self.poll_condition = threading.Condition()
-    self.is_polling = False
+    self.pluck_condition = threading.Condition()
+    self.num_plucking = 0
+    self.num_polling = 0
 
   cdef _interpret_event(self, grpc_event event):
     cdef OperationTag tag = None
@@ -87,19 +88,15 @@
       c_deadline = deadline.c_time
     cdef grpc_event event
 
-    # Poll within a critical section
-    # TODO(atash) consider making queue polling contention a hard error to
-    # enable easier bug discovery
-    with self.poll_condition:
-      while self.is_polling:
-        self.poll_condition.wait(float(deadline) - time.time())
-      self.is_polling = True
+    # Poll within a critical section to detect contention
+    with self.pluck_condition:
+      assert self.num_plucking == 0, 'cannot simultaneously pluck and poll'
+      self.num_polling += 1
     with nogil:
       event = grpc_completion_queue_next(
           self.c_completion_queue, c_deadline, NULL)
-    with self.poll_condition:
-      self.is_polling = False
-      self.poll_condition.notify()
+    with self.pluck_condition:
+      self.num_polling -= 1
     return self._interpret_event(event)
 
   def pluck(self, OperationTag tag, Timespec deadline=None):
@@ -111,19 +108,18 @@
       c_deadline = deadline.c_time
     cdef grpc_event event
 
-    # Poll within a critical section
-    # TODO(atash) consider making queue polling contention a hard error to
-    # enable easier bug discovery
-    with self.poll_condition:
-      while self.is_polling:
-        self.poll_condition.wait(float(deadline) - time.time())
-      self.is_polling = True
+    # Pluck within a critical section to detect contention
+    with self.pluck_condition:
+      assert self.num_polling == 0, 'cannot simultaneously pluck and poll'
+      assert self.num_plucking < GRPC_MAX_COMPLETION_QUEUE_PLUCKERS, (
+          'cannot pluck more than {} times simultaneously'.format(
+              GRPC_MAX_COMPLETION_QUEUE_PLUCKERS))
+      self.num_plucking += 1
     with nogil:
       event = grpc_completion_queue_pluck(
           self.c_completion_queue, <cpython.PyObject *>tag, c_deadline, NULL)
-    with self.poll_condition:
-      self.is_polling = False
-      self.poll_condition.notify()
+    with self.pluck_condition:
+      self.num_plucking -= 1
     return self._interpret_event(event)
 
   def shutdown(self):
@@ -137,10 +133,14 @@
       pass
 
   def __dealloc__(self):
+    cdef gpr_timespec c_deadline = gpr_inf_future(GPR_CLOCK_REALTIME)
     if self.c_completion_queue != NULL:
-      # Ensure shutdown, pump the queue
+      # Ensure shutdown
       if not self.is_shutting_down:
-        self.shutdown()
+        grpc_completion_queue_shutdown(self.c_completion_queue)
+      # Pump the queue
       while not self.is_shutdown:
-        self.poll()
+        event = grpc_completion_queue_next(
+            self.c_completion_queue, c_deadline, NULL)
+        self._interpret_event(event)
       grpc_completion_queue_destroy(self.c_completion_queue)
diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi
index 800d0ea..dbf0045 100644
--- a/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi
+++ b/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi
@@ -138,6 +138,8 @@
   const int GRPC_WRITE_NO_COMPRESS
   const int GRPC_WRITE_USED_MASK
 
+  const int GRPC_MAX_COMPLETION_QUEUE_PLUCKERS
+
   ctypedef struct grpc_completion_queue:
     # We don't care about the internals (and in fact don't know them)
     pass
diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/server.pxd.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/server.pxd.pxi
index 9db49e4..a344230 100644
--- a/src/python/grpcio/grpc/_cython/_cygrpc/server.pxd.pxi
+++ b/src/python/grpcio/grpc/_cython/_cygrpc/server.pxd.pxi
@@ -1,4 +1,4 @@
-# Copyright 2015, Google Inc.
+# Copyright 2015-2016, Google Inc.
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
@@ -39,4 +39,5 @@
   cdef list references
   cdef list registered_completion_queues
 
+  cdef _c_shutdown(self, CompletionQueue queue, tag)
   cdef notify_shutdown_complete(self)
diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/server.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/server.pyx.pxi
index 8b65935..fe93da6 100644
--- a/src/python/grpcio/grpc/_cython/_cygrpc/server.pyx.pxi
+++ b/src/python/grpcio/grpc/_cython/_cygrpc/server.pyx.pxi
@@ -1,4 +1,4 @@
-# Copyright 2015, Google Inc.
+# Copyright 2015-2016, Google Inc.
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
@@ -102,6 +102,16 @@
     else:
       return grpc_server_add_insecure_http2_port(self.c_server, address)
 
+  cdef _c_shutdown(self, CompletionQueue queue, tag):
+    self.is_shutting_down = True
+    operation_tag = OperationTag(tag)
+    operation_tag.shutting_down_server = self
+    operation_tag.references.extend([self, queue])
+    cpython.Py_INCREF(operation_tag)
+    grpc_server_shutdown_and_notify(
+        self.c_server, queue.c_completion_queue,
+        <cpython.PyObject *>operation_tag)
+
   def shutdown(self, CompletionQueue queue not None, tag):
     cdef OperationTag operation_tag
     if queue.is_shutting_down:
@@ -113,14 +123,7 @@
     elif queue not in self.registered_completion_queues:
       raise ValueError("expected registered completion queue")
     else:
-      self.is_shutting_down = True
-      operation_tag = OperationTag(tag)
-      operation_tag.shutting_down_server = self
-      operation_tag.references.extend([self, queue])
-      cpython.Py_INCREF(operation_tag)
-      grpc_server_shutdown_and_notify(
-          self.c_server, queue.c_completion_queue,
-          <cpython.PyObject *>operation_tag)
+      self._c_shutdown(queue, tag)
 
   cdef notify_shutdown_complete(self):
     # called only by a completion queue on receiving our shutdown operation tag
@@ -142,7 +145,7 @@
         pass
       elif not self.is_shutting_down:
         # the user didn't call shutdown - use our backup queue
-        self.shutdown(self.backup_shutdown_queue, None)
+        self._c_shutdown(self.backup_shutdown_queue, None)
         # and now we wait
         while not self.is_shutdown:
           self.backup_shutdown_queue.poll()
diff --git a/src/python/grpcio/grpc/_cython/imports.generated.c b/src/python/grpcio/grpc/_cython/imports.generated.c
index 4b1860c..8bd6ae6 100644
--- a/src/python/grpcio/grpc/_cython/imports.generated.c
+++ b/src/python/grpcio/grpc/_cython/imports.generated.c
@@ -220,6 +220,7 @@
 gpr_event_wait_type gpr_event_wait_import;
 gpr_ref_init_type gpr_ref_init_import;
 gpr_ref_type gpr_ref_import;
+gpr_ref_non_zero_type gpr_ref_non_zero_import;
 gpr_refn_type gpr_refn_import;
 gpr_unref_type gpr_unref_import;
 gpr_stats_init_type gpr_stats_init_import;
@@ -485,6 +486,7 @@
   gpr_event_wait_import = (gpr_event_wait_type) GetProcAddress(library, "gpr_event_wait");
   gpr_ref_init_import = (gpr_ref_init_type) GetProcAddress(library, "gpr_ref_init");
   gpr_ref_import = (gpr_ref_type) GetProcAddress(library, "gpr_ref");
+  gpr_ref_non_zero_import = (gpr_ref_non_zero_type) GetProcAddress(library, "gpr_ref_non_zero");
   gpr_refn_import = (gpr_refn_type) GetProcAddress(library, "gpr_refn");
   gpr_unref_import = (gpr_unref_type) GetProcAddress(library, "gpr_unref");
   gpr_stats_init_import = (gpr_stats_init_type) GetProcAddress(library, "gpr_stats_init");
diff --git a/src/python/grpcio/grpc/_cython/imports.generated.h b/src/python/grpcio/grpc/_cython/imports.generated.h
index ca30742..b70dccc 100644
--- a/src/python/grpcio/grpc/_cython/imports.generated.h
+++ b/src/python/grpcio/grpc/_cython/imports.generated.h
@@ -91,10 +91,10 @@
 typedef int(*census_context_get_tag_type)(const census_context *context, const char *key, census_tag *tag);
 extern census_context_get_tag_type census_context_get_tag_import;
 #define census_context_get_tag census_context_get_tag_import
-typedef char *(*census_context_encode_type)(const census_context *context, char *buffer, size_t buf_size, size_t *print_buf_size, size_t *bin_buf_size);
+typedef size_t(*census_context_encode_type)(const census_context *context, char *buffer, size_t buf_size);
 extern census_context_encode_type census_context_encode_import;
 #define census_context_encode census_context_encode_import
-typedef census_context *(*census_context_decode_type)(const char *buffer, size_t size, const char *bin_buffer, size_t bin_size);
+typedef census_context *(*census_context_decode_type)(const char *buffer, size_t size);
 extern census_context_decode_type census_context_decode_import;
 #define census_context_decode census_context_decode_import
 typedef int(*census_trace_mask_type)(const census_context *context);
@@ -610,6 +610,9 @@
 typedef void(*gpr_ref_type)(gpr_refcount *r);
 extern gpr_ref_type gpr_ref_import;
 #define gpr_ref gpr_ref_import
+typedef void(*gpr_ref_non_zero_type)(gpr_refcount *r);
+extern gpr_ref_non_zero_type gpr_ref_non_zero_import;
+#define gpr_ref_non_zero gpr_ref_non_zero_import
 typedef void(*gpr_refn_type)(gpr_refcount *r, int n);
 extern gpr_refn_type gpr_refn_import;
 #define gpr_refn gpr_refn_import
diff --git a/src/python/grpcio/grpc_core_dependencies.py b/src/python/grpcio/grpc_core_dependencies.py
index 38b2226..a543791 100644
--- a/src/python/grpcio/grpc_core_dependencies.py
+++ b/src/python/grpcio/grpc_core_dependencies.py
@@ -42,11 +42,9 @@
   'src/core/support/env_linux.c',
   'src/core/support/env_posix.c',
   'src/core/support/env_win32.c',
-  'src/core/support/file.c',
-  'src/core/support/file_posix.c',
-  'src/core/support/file_win32.c',
   'src/core/support/histogram.c',
   'src/core/support/host_port.c',
+  'src/core/support/load_file.c',
   'src/core/support/log.c',
   'src/core/support/log_android.c',
   'src/core/support/log_linux.c',
@@ -72,28 +70,9 @@
   'src/core/support/time_precise.c',
   'src/core/support/time_win32.c',
   'src/core/support/tls_pthread.c',
+  'src/core/support/tmpfile_posix.c',
+  'src/core/support/tmpfile_win32.c',
   'src/core/support/wrap_memcpy.c',
-  'src/core/httpcli/httpcli_security_connector.c',
-  'src/core/security/base64.c',
-  'src/core/security/client_auth_filter.c',
-  'src/core/security/credentials.c',
-  'src/core/security/credentials_metadata.c',
-  'src/core/security/credentials_posix.c',
-  'src/core/security/credentials_win32.c',
-  'src/core/security/google_default_credentials.c',
-  'src/core/security/handshake.c',
-  'src/core/security/json_token.c',
-  'src/core/security/jwt_verifier.c',
-  'src/core/security/secure_endpoint.c',
-  'src/core/security/security_connector.c',
-  'src/core/security/security_context.c',
-  'src/core/security/server_auth_filter.c',
-  'src/core/security/server_secure_chttp2.c',
-  'src/core/surface/init_secure.c',
-  'src/core/surface/secure_channel_create.c',
-  'src/core/tsi/fake_transport_security.c',
-  'src/core/tsi/ssl_transport_security.c',
-  'src/core/tsi/transport_security.c',
   'src/core/census/grpc_context.c',
   'src/core/census/grpc_filter.c',
   'src/core/channel/channel_args.c',
@@ -109,6 +88,7 @@
   'src/core/client_config/connector.c',
   'src/core/client_config/default_initial_connect_string.c',
   'src/core/client_config/initial_connect_string.c',
+  'src/core/client_config/lb_policies/load_balancer_api.c',
   'src/core/client_config/lb_policies/pick_first.c',
   'src/core/client_config/lb_policies/round_robin.c',
   'src/core/client_config/lb_policy.c',
@@ -123,7 +103,7 @@
   'src/core/client_config/subchannel_factory.c',
   'src/core/client_config/subchannel_index.c',
   'src/core/client_config/uri_parser.c',
-  'src/core/compression/algorithm.c',
+  'src/core/compression/compression_algorithm.c',
   'src/core/compression/message_compress.c',
   'src/core/debug/trace.c',
   'src/core/httpcli/format_request.c',
@@ -173,6 +153,7 @@
   'src/core/json/json_reader.c',
   'src/core/json/json_string.c',
   'src/core/json/json_writer.c',
+  'src/core/proto/grpc/lb/v0/load_balancer.pb.c',
   'src/core/surface/alarm.c',
   'src/core/surface/api_trace.c',
   'src/core/surface/byte_buffer.c',
@@ -222,12 +203,36 @@
   'src/core/transport/static_metadata.c',
   'src/core/transport/transport.c',
   'src/core/transport/transport_op_string.c',
+  'src/core/httpcli/httpcli_security_connector.c',
+  'src/core/security/b64.c',
+  'src/core/security/client_auth_filter.c',
+  'src/core/security/credentials.c',
+  'src/core/security/credentials_metadata.c',
+  'src/core/security/credentials_posix.c',
+  'src/core/security/credentials_win32.c',
+  'src/core/security/google_default_credentials.c',
+  'src/core/security/handshake.c',
+  'src/core/security/json_token.c',
+  'src/core/security/jwt_verifier.c',
+  'src/core/security/secure_endpoint.c',
+  'src/core/security/security_connector.c',
+  'src/core/security/security_context.c',
+  'src/core/security/server_auth_filter.c',
+  'src/core/security/server_secure_chttp2.c',
+  'src/core/surface/init_secure.c',
+  'src/core/surface/secure_channel_create.c',
+  'src/core/tsi/fake_transport_security.c',
+  'src/core/tsi/ssl_transport_security.c',
+  'src/core/tsi/transport_security.c',
   'src/core/census/context.c',
   'src/core/census/initialize.c',
-  'src/core/census/log.c',
+  'src/core/census/mlog.c',
   'src/core/census/operation.c',
   'src/core/census/placeholders.c',
   'src/core/census/tracing.c',
+  'third_party/nanopb/pb_common.c',
+  'third_party/nanopb/pb_decode.c',
+  'third_party/nanopb/pb_encode.c',
   'src/boringssl/err_data.c',
   'third_party/boringssl/crypto/aes/aes.c',
   'third_party/boringssl/crypto/aes/mode_wrappers.c',
diff --git a/src/python/grpcio/precompiled.py b/src/python/grpcio/precompiled.py
index 05c651b..ae2a0c8 100644
--- a/src/python/grpcio/precompiled.py
+++ b/src/python/grpcio/precompiled.py
@@ -100,3 +100,5 @@
     sys.stderr.write(
         'could not write precompiled extension to directory: {} -> {}\n'
             .format(url, target_path))
+    return
+  setup_arguments['package_data']['grpc._cython'].append('cygrpc.so')
diff --git a/src/python/grpcio_health_checking/grpc/health/v1alpha/__init__.py b/src/python/grpcio_health_checking/grpc/health/v1/__init__.py
similarity index 97%
rename from src/python/grpcio_health_checking/grpc/health/v1alpha/__init__.py
rename to src/python/grpcio_health_checking/grpc/health/v1/__init__.py
index 7086519..13aac79 100644
--- a/src/python/grpcio_health_checking/grpc/health/v1alpha/__init__.py
+++ b/src/python/grpcio_health_checking/grpc/health/v1/__init__.py
@@ -1,4 +1,4 @@
-# Copyright 2015, Google Inc.
+# Copyright 2015-2016, Google Inc.
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
diff --git a/src/python/grpcio_health_checking/grpc/health/v1alpha/health.proto b/src/python/grpcio_health_checking/grpc/health/v1/health.proto
similarity index 96%
rename from src/python/grpcio_health_checking/grpc/health/v1alpha/health.proto
rename to src/python/grpcio_health_checking/grpc/health/v1/health.proto
index 57f4aaa..de10719 100644
--- a/src/python/grpcio_health_checking/grpc/health/v1alpha/health.proto
+++ b/src/python/grpcio_health_checking/grpc/health/v1/health.proto
@@ -1,4 +1,4 @@
-// Copyright 2015, Google Inc.
+// Copyright 2015-2016, Google Inc.
 // All rights reserved.
 //
 // Redistribution and use in source and binary forms, with or without
@@ -29,7 +29,7 @@
 
 syntax = "proto3";
 
-package grpc.health.v1alpha;
+package grpc.health.v1;
 
 message HealthCheckRequest {
   string service = 1;
diff --git a/src/python/grpcio_health_checking/grpc/health/v1alpha/health.py b/src/python/grpcio_health_checking/grpc/health/v1/health.py
similarity index 96%
rename from src/python/grpcio_health_checking/grpc/health/v1alpha/health.py
rename to src/python/grpcio_health_checking/grpc/health/v1/health.py
index 9dfcd96..60cbd644 100644
--- a/src/python/grpcio_health_checking/grpc/health/v1alpha/health.py
+++ b/src/python/grpcio_health_checking/grpc/health/v1/health.py
@@ -1,4 +1,4 @@
-# Copyright 2015, Google Inc.
+# Copyright 2015-2016, Google Inc.
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
@@ -33,7 +33,7 @@
 import enum
 import threading
 
-from grpc.health.v1alpha import health_pb2
+from grpc.health.v1 import health_pb2
 
 
 @enum.unique
@@ -64,7 +64,7 @@
 
   def set(service, status):
     if not isinstance(status, HealthStatus):
-      raise TypeError('expected grpc.health.v1alpha.health.HealthStatus '
+      raise TypeError('expected grpc.health.v1.health.HealthStatus '
                       'for argument `status` but got {}'.format(status))
     with self._server_status_lock:
       self._server_status[service] = status
diff --git a/src/ruby/.rubocop.yml b/src/ruby/.rubocop.yml
index dd57ab6..ff5cf8d 100644
--- a/src/ruby/.rubocop.yml
+++ b/src/ruby/.rubocop.yml
@@ -7,7 +7,7 @@
     - 'bin/apis/**/*'
     - 'bin/math.rb'
     - 'bin/math_services.rb'
-    - 'pb/grpc/health/v1alpha/*'
+    - 'pb/grpc/health/v1/*'
     - 'pb/test/**/*'
 
 Metrics/CyclomaticComplexity:
diff --git a/src/ruby/ext/grpc/rb_grpc.c b/src/ruby/ext/grpc/rb_grpc.c
index eefdb93..0f9b18f 100644
--- a/src/ruby/ext/grpc/rb_grpc.c
+++ b/src/ruby/ext/grpc/rb_grpc.c
@@ -269,20 +269,9 @@
   id_tv_nsec = rb_intern("tv_nsec");
 }
 
-/*
-   TODO: find an alternative to ruby_vm_at_exit that is ok in Ruby 2.0 where
-   RUBY_TYPED_FREE_IMMEDIATELY is not defined.
-
-   At the moment, registering a function using ruby_vm_at_exit segfaults in Ruby
-   2.0.  This is not an issue with the gRPC handler.  More likely, this was an
-   in issue with 2.0 that got resolved in 2.1 and has not been backported.
-*/
-#ifdef RUBY_TYPED_FREE_IMMEDIATELY
-static void grpc_rb_shutdown(ruby_vm_t *vm) {
-  (void)vm;
+static void grpc_rb_shutdown(void) {
   grpc_shutdown();
 }
-#endif
 
 /* Initialize the GRPC module structs */
 
@@ -300,18 +289,30 @@
 VALUE sym_details = Qundef;
 VALUE sym_metadata = Qundef;
 
+static gpr_once g_once_init = GPR_ONCE_INIT;
+
+static void grpc_ruby_once_init() {
+  grpc_init();
+  atexit(grpc_rb_shutdown);
+}
+
 void Init_grpc_c() {
   if (!grpc_rb_load_core()) {
     rb_raise(rb_eLoadError, "Couldn't find or load gRPC's dynamic C core");
     return;
   }
 
-  grpc_init();
-
-/* TODO: find alternative to ruby_vm_at_exit that is ok in Ruby 2.0 */
-#ifdef RUBY_TYPED_FREE_IMMEDIATELY
-  ruby_vm_at_exit(grpc_rb_shutdown);
-#endif
+  /* ruby_vm_at_exit doesn't seem to be working. It would crash once every
+   * blue moon, and some users are getting it repeatedly. See the discussions
+   *  - https://github.com/grpc/grpc/pull/5337
+   *  - https://bugs.ruby-lang.org/issues/12095
+   *
+   * In order to still be able to handle the (unlikely) situation where the
+   * extension is loaded by a first Ruby VM that is subsequently destroyed,
+   * then loaded again by another VM within the same process, we need to
+   * schedule our initialization and destruction only once.
+   */
+  gpr_once_init(&g_once_init, grpc_ruby_once_init);
 
   grpc_rb_mGRPC = rb_define_module("GRPC");
   grpc_rb_mGrpcCore = rb_define_module_under(grpc_rb_mGRPC, "Core");
diff --git a/src/ruby/ext/grpc/rb_grpc_imports.generated.c b/src/ruby/ext/grpc/rb_grpc_imports.generated.c
index 1af34d9..56db4ec 100644
--- a/src/ruby/ext/grpc/rb_grpc_imports.generated.c
+++ b/src/ruby/ext/grpc/rb_grpc_imports.generated.c
@@ -220,6 +220,7 @@
 gpr_event_wait_type gpr_event_wait_import;
 gpr_ref_init_type gpr_ref_init_import;
 gpr_ref_type gpr_ref_import;
+gpr_ref_non_zero_type gpr_ref_non_zero_import;
 gpr_refn_type gpr_refn_import;
 gpr_unref_type gpr_unref_import;
 gpr_stats_init_type gpr_stats_init_import;
@@ -481,6 +482,7 @@
   gpr_event_wait_import = (gpr_event_wait_type) GetProcAddress(library, "gpr_event_wait");
   gpr_ref_init_import = (gpr_ref_init_type) GetProcAddress(library, "gpr_ref_init");
   gpr_ref_import = (gpr_ref_type) GetProcAddress(library, "gpr_ref");
+  gpr_ref_non_zero_import = (gpr_ref_non_zero_type) GetProcAddress(library, "gpr_ref_non_zero");
   gpr_refn_import = (gpr_refn_type) GetProcAddress(library, "gpr_refn");
   gpr_unref_import = (gpr_unref_type) GetProcAddress(library, "gpr_unref");
   gpr_stats_init_import = (gpr_stats_init_type) GetProcAddress(library, "gpr_stats_init");
diff --git a/src/ruby/ext/grpc/rb_grpc_imports.generated.h b/src/ruby/ext/grpc/rb_grpc_imports.generated.h
index b61c528..b972f60 100644
--- a/src/ruby/ext/grpc/rb_grpc_imports.generated.h
+++ b/src/ruby/ext/grpc/rb_grpc_imports.generated.h
@@ -91,10 +91,10 @@
 typedef int(*census_context_get_tag_type)(const census_context *context, const char *key, census_tag *tag);
 extern census_context_get_tag_type census_context_get_tag_import;
 #define census_context_get_tag census_context_get_tag_import
-typedef char *(*census_context_encode_type)(const census_context *context, char *buffer, size_t buf_size, size_t *print_buf_size, size_t *bin_buf_size);
+typedef size_t(*census_context_encode_type)(const census_context *context, char *buffer, size_t buf_size);
 extern census_context_encode_type census_context_encode_import;
 #define census_context_encode census_context_encode_import
-typedef census_context *(*census_context_decode_type)(const char *buffer, size_t size, const char *bin_buffer, size_t bin_size);
+typedef census_context *(*census_context_decode_type)(const char *buffer, size_t size);
 extern census_context_decode_type census_context_decode_import;
 #define census_context_decode census_context_decode_import
 typedef int(*census_trace_mask_type)(const census_context *context);
@@ -610,6 +610,9 @@
 typedef void(*gpr_ref_type)(gpr_refcount *r);
 extern gpr_ref_type gpr_ref_import;
 #define gpr_ref gpr_ref_import
+typedef void(*gpr_ref_non_zero_type)(gpr_refcount *r);
+extern gpr_ref_non_zero_type gpr_ref_non_zero_import;
+#define gpr_ref_non_zero gpr_ref_non_zero_import
 typedef void(*gpr_refn_type)(gpr_refcount *r, int n);
 extern gpr_refn_type gpr_refn_import;
 #define gpr_refn gpr_refn_import
diff --git a/src/ruby/lib/grpc/core/time_consts.rb b/src/ruby/lib/grpc/core/time_consts.rb
index e6dae7b..c8eae78 100644
--- a/src/ruby/lib/grpc/core/time_consts.rb
+++ b/src/ruby/lib/grpc/core/time_consts.rb
@@ -1,4 +1,4 @@
-# Copyright 2015, Google Inc.
+# Copyright 2015-2016, Google Inc.
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
@@ -27,7 +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.
 
-require 'grpc'
+require 'grpc/grpc'
 
 # GRPC contains the General RPC module.
 module GRPC
diff --git a/src/ruby/lib/grpc/errors.rb b/src/ruby/lib/grpc/errors.rb
index f1201c1..2227ee1 100644
--- a/src/ruby/lib/grpc/errors.rb
+++ b/src/ruby/lib/grpc/errors.rb
@@ -1,4 +1,4 @@
-# Copyright 2015, Google Inc.
+# Copyright 2015-2016, Google Inc.
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
@@ -27,7 +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.
 
-require 'grpc'
+require 'grpc/grpc'
 
 # GRPC contains the General RPC module.
 module GRPC
diff --git a/src/ruby/pb/README.md b/src/ruby/pb/README.md
index e04aef1..d9e30bb 100644
--- a/src/ruby/pb/README.md
+++ b/src/ruby/pb/README.md
@@ -11,7 +11,7 @@
 grpc_ruby_plugin.  These must be installed to regenerate the IDL defined
 classes, but that's not necessary just to use them.
 
-health_check/v1alpha
+health_check/v1
 --------------------
 
 This package defines the surface of a simple health check service that gRPC
@@ -20,7 +20,7 @@
 
 ```bash
 $ # (from this directory)
-$ protoc -I ../../proto ../../proto/grpc/health/v1alpha/health.proto \
+$ protoc -I ../../proto ../../proto/grpc/health/v1/health.proto \
     --grpc_out=. \
     --ruby_out=. \
     --plugin=protoc-gen-grpc=`which grpc_ruby_plugin`
diff --git a/src/ruby/pb/generate_proto_ruby.sh b/src/ruby/pb/generate_proto_ruby.sh
index 576b1c0..86c0820 100755
--- a/src/ruby/pb/generate_proto_ruby.sh
+++ b/src/ruby/pb/generate_proto_ruby.sh
@@ -1,5 +1,5 @@
 #!/bin/sh
-# Copyright 2015, Google Inc.
+# Copyright 2015-2016, Google Inc.
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
@@ -35,7 +35,7 @@
 PROTOC=bins/opt/protobuf/protoc
 PLUGIN=protoc-gen-grpc=bins/opt/grpc_ruby_plugin
 
-$PROTOC -I src/proto src/proto/grpc/health/v1alpha/health.proto \
+$PROTOC -I src/proto src/proto/grpc/health/v1/health.proto \
     --grpc_out=src/ruby/pb \
     --ruby_out=src/ruby/pb \
     --plugin=$PLUGIN
diff --git a/src/ruby/pb/grpc/health/checker.rb b/src/ruby/pb/grpc/health/checker.rb
index 8c692e7..9f1ee65 100644
--- a/src/ruby/pb/grpc/health/checker.rb
+++ b/src/ruby/pb/grpc/health/checker.rb
@@ -1,4 +1,4 @@
-# Copyright 2015, Google Inc.
+# Copyright 2015-2016, Google Inc.
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
@@ -28,7 +28,7 @@
 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 require 'grpc'
-require 'grpc/health/v1alpha/health_services'
+require 'grpc/health/v1/health_services'
 require 'thread'
 
 module Grpc
@@ -36,9 +36,9 @@
   # service.
   module Health
     # Checker is implementation of the schema-specified health checking service.
-    class Checker < V1alpha::Health::Service
+    class Checker < V1::Health::Service
       StatusCodes = GRPC::Core::StatusCodes
-      HealthCheckResponse = V1alpha::HealthCheckResponse
+      HealthCheckResponse = V1::HealthCheckResponse
 
       # Initializes the statuses of participating services
       def initialize
@@ -50,20 +50,20 @@
       def check(req, _call)
         status = nil
         @status_mutex.synchronize do
-          status = @statuses["#{req.host}/#{req.service}"]
+          status = @statuses["#{req.service}"]
         end
         fail GRPC::BadStatus, StatusCodes::NOT_FOUND if status.nil?
         HealthCheckResponse.new(status: status)
       end
 
-      # Adds the health status for a given host and service.
-      def add_status(host, service, status)
-        @status_mutex.synchronize { @statuses["#{host}/#{service}"] = status }
+      # Adds the health status for a given service.
+      def add_status(service, status)
+        @status_mutex.synchronize { @statuses["#{service}"] = status }
       end
 
-      # Clears the status for the given host or service.
-      def clear_status(host, service)
-        @status_mutex.synchronize { @statuses.delete("#{host}/#{service}") }
+      # Clears the status for the given service.
+      def clear_status(service)
+        @status_mutex.synchronize { @statuses.delete("#{service}") }
       end
 
       # Clears alls the statuses.
diff --git a/src/ruby/pb/grpc/health/v1/health.rb b/src/ruby/pb/grpc/health/v1/health.rb
new file mode 100644
index 0000000..aa87a93
--- /dev/null
+++ b/src/ruby/pb/grpc/health/v1/health.rb
@@ -0,0 +1,28 @@
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: grpc/health/v1/health.proto
+
+require 'google/protobuf'
+
+Google::Protobuf::DescriptorPool.generated_pool.build do
+  add_message "grpc.health.v1.HealthCheckRequest" do
+    optional :service, :string, 1
+  end
+  add_message "grpc.health.v1.HealthCheckResponse" do
+    optional :status, :enum, 1, "grpc.health.v1.HealthCheckResponse.ServingStatus"
+  end
+  add_enum "grpc.health.v1.HealthCheckResponse.ServingStatus" do
+    value :UNKNOWN, 0
+    value :SERVING, 1
+    value :NOT_SERVING, 2
+  end
+end
+
+module Grpc
+  module Health
+    module V1
+      HealthCheckRequest = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.health.v1.HealthCheckRequest").msgclass
+      HealthCheckResponse = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.health.v1.HealthCheckResponse").msgclass
+      HealthCheckResponse::ServingStatus = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.health.v1.HealthCheckResponse.ServingStatus").enummodule
+    end
+  end
+end
diff --git a/src/ruby/pb/grpc/health/v1alpha/health_services.rb b/src/ruby/pb/grpc/health/v1/health_services.rb
similarity index 71%
rename from src/ruby/pb/grpc/health/v1alpha/health_services.rb
rename to src/ruby/pb/grpc/health/v1/health_services.rb
index d5cba2e..cb79b20 100644
--- a/src/ruby/pb/grpc/health/v1alpha/health_services.rb
+++ b/src/ruby/pb/grpc/health/v1/health_services.rb
@@ -1,12 +1,12 @@
 # Generated by the protocol buffer compiler.  DO NOT EDIT!
-# Source: grpc/health/v1alpha/health.proto for package 'grpc.health.v1alpha'
+# Source: grpc/health/v1/health.proto for package 'grpc.health.v1'
 
 require 'grpc'
-require 'grpc/health/v1alpha/health'
+require 'grpc/health/v1/health'
 
 module Grpc
   module Health
-    module V1alpha
+    module V1
       module Health
 
         # TODO: add proto service documentation here
@@ -16,7 +16,7 @@
 
           self.marshal_class_method = :encode
           self.unmarshal_class_method = :decode
-          self.service_name = 'grpc.health.v1alpha.Health'
+          self.service_name = 'grpc.health.v1.Health'
 
           rpc :Check, HealthCheckRequest, HealthCheckResponse
         end
diff --git a/src/ruby/pb/grpc/health/v1alpha/health.rb b/src/ruby/pb/grpc/health/v1alpha/health.rb
deleted file mode 100644
index 9c04298..0000000
--- a/src/ruby/pb/grpc/health/v1alpha/health.rb
+++ /dev/null
@@ -1,29 +0,0 @@
-# Generated by the protocol buffer compiler.  DO NOT EDIT!
-# source: grpc/health/v1alpha/health.proto
-
-require 'google/protobuf'
-
-Google::Protobuf::DescriptorPool.generated_pool.build do
-  add_message "grpc.health.v1alpha.HealthCheckRequest" do
-    optional :host, :string, 1
-    optional :service, :string, 2
-  end
-  add_message "grpc.health.v1alpha.HealthCheckResponse" do
-    optional :status, :enum, 1, "grpc.health.v1alpha.HealthCheckResponse.ServingStatus"
-  end
-  add_enum "grpc.health.v1alpha.HealthCheckResponse.ServingStatus" do
-    value :UNKNOWN, 0
-    value :SERVING, 1
-    value :NOT_SERVING, 2
-  end
-end
-
-module Grpc
-  module Health
-    module V1alpha
-      HealthCheckRequest = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.health.v1alpha.HealthCheckRequest").msgclass
-      HealthCheckResponse = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.health.v1alpha.HealthCheckResponse").msgclass
-      HealthCheckResponse::ServingStatus = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.health.v1alpha.HealthCheckResponse.ServingStatus").enummodule
-    end
-  end
-end
diff --git a/src/ruby/spec/pb/health/checker_spec.rb b/src/ruby/spec/pb/health/checker_spec.rb
index c1decd8..9bb79bb 100644
--- a/src/ruby/spec/pb/health/checker_spec.rb
+++ b/src/ruby/spec/pb/health/checker_spec.rb
@@ -28,7 +28,7 @@
 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 require 'grpc'
-require 'grpc/health/v1alpha/health'
+require 'grpc/health/v1/health'
 require 'grpc/health/checker'
 require 'open3'
 require 'tmpdir'
@@ -43,7 +43,7 @@
       skip 'protoc || grpc_ruby_plugin missing, cannot verify health code-gen'
     else
       it 'should already be loaded indirectly i.e, used by the other specs' do
-        expect(require('grpc/health/v1alpha/health_services')).to be(false)
+        expect(require('grpc/health/v1/health_services')).to be(false)
       end
 
       it 'should have the same content as created by code generation' do
@@ -52,7 +52,7 @@
 
         # Get the current content
         service_path = File.join(root_dir, 'ruby', 'pb', 'grpc',
-                                 'health', 'v1alpha', 'health_services.rb')
+                                 'health', 'v1', 'health_services.rb')
         want = nil
         File.open(service_path) { |f| want = f.read }
 
@@ -61,12 +61,12 @@
         plugin = plugin.strip
         got = nil
         Dir.mktmpdir do |tmp_dir|
-          gen_out = File.join(tmp_dir, 'grpc', 'health', 'v1alpha',
+          gen_out = File.join(tmp_dir, 'grpc', 'health', 'v1',
                               'health_services.rb')
           pid = spawn(
             'protoc',
             '-I.',
-            'grpc/health/v1alpha/health.proto',
+            'grpc/health/v1/health.proto',
             "--grpc_out=#{tmp_dir}",
             "--plugin=protoc-gen-grpc=#{plugin}",
             chdir: pb_dir)
@@ -81,27 +81,17 @@
 
 describe Grpc::Health::Checker do
   StatusCodes = GRPC::Core::StatusCodes
-  ServingStatus = Grpc::Health::V1alpha::HealthCheckResponse::ServingStatus
-  HCResp = Grpc::Health::V1alpha::HealthCheckResponse
-  HCReq = Grpc::Health::V1alpha::HealthCheckRequest
+  ServingStatus = Grpc::Health::V1::HealthCheckResponse::ServingStatus
+  HCResp = Grpc::Health::V1::HealthCheckResponse
+  HCReq = Grpc::Health::V1::HealthCheckRequest
   success_tests =
     [
       {
-        desc: 'neither host or service are specified',
-        host: '',
+        desc: 'the service is not specified',
         service: ''
       }, {
-        desc: 'only the host is specified',
-        host: 'test-fake-host',
-        service: ''
-      }, {
-        desc: 'the host and service are specified',
-        host: 'test-fake-host',
+        desc: 'the service is specified',
         service: 'fake-service-1'
-      }, {
-        desc: 'only the service is specified',
-        host: '',
-        service: 'fake-service-2'
       }
     ]
 
@@ -114,9 +104,8 @@
   context 'method `add_status` and `check`' do
     success_tests.each do |t|
       it "should succeed when #{t[:desc]}" do
-        subject.add_status(t[:host], t[:service], ServingStatus::NOT_SERVING)
-        got = subject.check(HCReq.new(host: t[:host], service: t[:service]),
-                            nil)
+        subject.add_status(t[:service], ServingStatus::NOT_SERVING)
+        got = subject.check(HCReq.new(service: t[:service]), nil)
         want = HCResp.new(status: ServingStatus::NOT_SERVING)
         expect(got).to eq(want)
       end
@@ -127,7 +116,7 @@
     success_tests.each do |t|
       it "should fail with NOT_FOUND when #{t[:desc]}" do
         blk = proc do
-          subject.check(HCReq.new(host: t[:host], service: t[:service]), nil)
+          subject.check(HCReq.new(service: t[:service]), nil)
         end
         expected_msg = /#{StatusCodes::NOT_FOUND}/
         expect(&blk).to raise_error GRPC::BadStatus, expected_msg
@@ -138,16 +127,14 @@
   context 'method `clear_status`' do
     success_tests.each do |t|
       it "should fail after clearing status when #{t[:desc]}" do
-        subject.add_status(t[:host], t[:service], ServingStatus::NOT_SERVING)
-        got = subject.check(HCReq.new(host: t[:host], service: t[:service]),
-                            nil)
+        subject.add_status(t[:service], ServingStatus::NOT_SERVING)
+        got = subject.check(HCReq.new(service: t[:service]), nil)
         want = HCResp.new(status: ServingStatus::NOT_SERVING)
         expect(got).to eq(want)
 
-        subject.clear_status(t[:host], t[:service])
+        subject.clear_status(t[:service])
         blk = proc do
-          subject.check(HCReq.new(host: t[:host], service: t[:service]),
-                        nil)
+          subject.check(HCReq.new(service: t[:service]), nil)
         end
         expected_msg = /#{StatusCodes::NOT_FOUND}/
         expect(&blk).to raise_error GRPC::BadStatus, expected_msg
@@ -158,9 +145,8 @@
   context 'method `clear_all`' do
     it 'should return NOT_FOUND after being invoked' do
       success_tests.each do |t|
-        subject.add_status(t[:host], t[:service], ServingStatus::NOT_SERVING)
-        got = subject.check(HCReq.new(host: t[:host], service: t[:service]),
-                            nil)
+        subject.add_status(t[:service], ServingStatus::NOT_SERVING)
+        got = subject.check(HCReq.new(service: t[:service]), nil)
         want = HCResp.new(status: ServingStatus::NOT_SERVING)
         expect(got).to eq(want)
       end
@@ -169,7 +155,7 @@
 
       success_tests.each do |t|
         blk = proc do
-          subject.check(HCReq.new(host: t[:host], service: t[:service]), nil)
+          subject.check(HCReq.new(service: t[:service]), nil)
         end
         expected_msg = /#{StatusCodes::NOT_FOUND}/
         expect(&blk).to raise_error GRPC::BadStatus, expected_msg
@@ -203,7 +189,7 @@
 
     it 'should receive the correct status', server: true do
       @srv.handle(subject)
-      subject.add_status('', '', ServingStatus::NOT_SERVING)
+      subject.add_status('', ServingStatus::NOT_SERVING)
       t = Thread.new { @srv.run }
       @srv.wait_till_running
 
@@ -221,7 +207,7 @@
       @srv.wait_till_running
       blk = proc do
         stub = CheckerStub.new(@host, :this_channel_is_insecure, **@client_opts)
-        stub.check(HCReq.new(host: 'unknown', service: 'unknown'))
+        stub.check(HCReq.new(service: 'unknown'))
       end
       expected_msg = /#{StatusCodes::NOT_FOUND}/
       expect(&blk).to raise_error GRPC::BadStatus, expected_msg
diff --git a/summerofcode/ideas.md b/summerofcode/ideas.md
new file mode 100644
index 0000000..c7f368e
--- /dev/null
+++ b/summerofcode/ideas.md
@@ -0,0 +1,52 @@
+# gRPC Summer of Code Project Ideas
+
+Hello students!
+
+We want gRPC to be the universal remote procedure call protocol for all
+computing platforms and paradigms, so while these are our ideas of what we
+think would make good projects for the summer, we're eager to hear your ideas
+and proposals as well.
+[Try us out](https://github.com/grpc/grpc/blob/master/CONTRIBUTING.md) and get
+to know the gRPC code and team!
+
+**Required skills for all projects:** git version control, collaborative
+software development on github.com, and software development in at least one
+of gRPC's ten languages on at least one of Linux, Mac OS X, and Windows.
+
+-------------------------------------
+
+gRPC C Core:
+
+1. Port gRPC to  one of the major BSD platforms ([FreeBSD](https://freebsd.org), [NetBSD](https://netbsd.org), and [OpenBSD](https://openbsd.org)) and create packages for them. Add [kqueue](https://www.freebsd.org/cgi/man.cgi?query=kqueue) support in the process.
+ * **Required skills:** C programming language, BSD operating system.
+ * **Likely mentors:** [Craig Tiller](https://github.com/ctiller), [Nicolas Noble](https://github.com/nicolasnoble).
+1. Fix gRPC C-core's URI parser. The current parser does not qualify as a standard parser according to [RFC3986]( https://tools.ietf.org/html/rfc3986). Write test suites to verify this and make changes necessary to make the URI parser compliant.
+ * **Required skills:** C programming language, HTTP standard compliance.
+ * **Likely mentors:** [Craig Tiller](https://github.com/ctiller).
+1. HPACK compression efficiency evaluation - Figure out how to benchmark gRPC's compression efficiency (both in terms of bytes on the wire and cpu cycles). Implement benchmarks. Potentially extend this to other full-stack gRPC implementations (Java and Go).
+ * **Required skills:** C programming language, software performance benchmarking, potentially Java and Go.
+ * **Likely mentors:** [Craig Tiller](https://github.com/ctiller).
+
+
+gRPC Python:
+
+1. Port gRPC Python to [PyPy](http://pypy.org). Investigate the state of [Cython support](http://docs.cython.org/src/userguide/pypy.html) to do this or potentially explore [cffi](https://cffi.readthedocs.org/en/latest/).
+ * **Required skills:** Python programming language, PyPy Python interpreter.
+ * **Likely mentors:** [Nathaniel Manista](https://github.com/nathanielmanistaatgoogle), [Masood Malekghassemi](https://github.com/soltanmm).
+1. Develop and test Python 3.5 Support for gRPC. Make necessary changes to port gRPC and package it for supported platforms.
+ * **Required skills:** Python programming language, PyPy Python interpreter.
+ * **Likely mentors:** [Nathaniel Manista](https://github.com/nathanielmanistaatgoogle), [Masood Malekghassemi](https://github.com/soltanmm).
+ 
+gRPC Ruby/Java:
+
+1. [jRuby](http://jruby.org) support for gRPC. Develop a jRuby wrapper for gRPC based on grpc-java and ensure that it is API compatible with the existing Ruby implementation and passes all tests.
+ * **Required skills:** Java programming language, Ruby programming language.
+ * **Likely mentors:** [Michael Lumish](https://github.com/murgatroid99), [Eric Anderson](https://github.com/ejona86).
+
+
+gRPC Wire Protocol:
+
+1. Develop a [Wireshark](https://wireshark.org) plugin for the gRPC protocol. Provide documentation and tutorials for this plugin.
+ * **Bonus:** consider set-up and use with mobile clients.
+ * **Required skills:** Wireshark software.
+ * **Likely mentors:** [Nicolas Noble](https://github.com/nicolasnoble).
diff --git a/templates/Makefile.template b/templates/Makefile.template
index 218f492..c54c146 100644
--- a/templates/Makefile.template
+++ b/templates/Makefile.template
@@ -159,7 +159,7 @@
   else
   ifeq ($(SYSTEM),Darwin)
   ifeq ($(origin AR), default)
-  AR = libtool -o
+  AR = libtool -no_warning_for_no_symbols -o
   endif
   STRIP ?= strip -x
   else
@@ -187,6 +187,12 @@
   CXX11_CHECK_CMD = $(CXX) -std=c++11 -o $(TMPOUT) -c test/build/c++11.cc
   HAS_CXX11 = $(shell $(CXX11_CHECK_CMD) 2> /dev/null && echo true || echo false)
 
+  CHECK_SHADOW_WORKS_CMD = $(CC) -std=c99 -Werror -Wshadow -o $(TMPOUT) -c test/build/shadow.c
+  HAS_WORKING_SHADOW = $(shell $(CHECK_SHADOW_WORKS_CMD) 2> /dev/null && echo true || echo false)
+  ifeq ($(HAS_WORKING_SHADOW),true)
+  W_SHADOW=-Wshadow
+  endif
+
   CHECK_NO_SHIFT_NEGATIVE_VALUE_CMD = $(CC) -std=c99 -Werror -Wno-shift-negative-value -o $(TMPOUT) -c test/build/empty.c
   HAS_NO_SHIFT_NEGATIVE_VALUE = $(shell $(CHECK_NO_SHIFT_NEGATIVE_VALUE_CMD) 2> /dev/null && echo true || echo false)
   ifeq ($(HAS_NO_SHIFT_NEGATIVE_VALUE),true)
@@ -207,7 +213,7 @@
   DEFINES += $(EXTRA_DEFINES)
   endif
 
-  CFLAGS += -std=c99 -Wsign-conversion -Wconversion -Wshadow
+  CFLAGS += -std=c99 -Wsign-conversion -Wconversion $(W_SHADOW)
   ifeq ($(HAS_CXX11),true)
   CXXFLAGS += -std=c++11
   else
@@ -352,6 +358,7 @@
 
   OPENSSL_ALPN_CHECK_CMD = $(CC) $(CPPFLAGS) $(CFLAGS) -o $(TMPOUT) test/build/openssl-alpn.c $(addprefix -l, $(OPENSSL_LIBS)) $(LDFLAGS)
   OPENSSL_NPN_CHECK_CMD = $(CC) $(CPPFLAGS) $(CFLAGS) -o $(TMPOUT) test/build/openssl-npn.c $(addprefix -l, $(OPENSSL_LIBS)) $(LDFLAGS)
+  BORINGSSL_COMPILE_CHECK_CMD = $(CC) $(CPPFLAGS) ${defaults.boringssl.CPPFLAGS} $(CFLAGS) ${defaults.boringssl.CFLAGS} -o $(TMPOUT) test/build/boringssl.c $(LDFLAGS)
   ZLIB_CHECK_CMD = $(CC) $(CPPFLAGS) $(CFLAGS) -o $(TMPOUT) test/build/zlib.c -lz $(LDFLAGS)
   PROTOBUF_CHECK_CMD = $(CXX) $(CPPFLAGS) $(CXXFLAGS) -o $(TMPOUT) test/build/protobuf.cc -lprotobuf $(LDFLAGS)
 
@@ -436,10 +443,13 @@
   # Note that for testing purposes, one can do:
   #   make HAS_EMBEDDED_OPENSSL_ALPN=false
   # to emulate the fact we do not have OpenSSL in the third_party folder.
-  ifeq ($(wildcard third_party/boringssl/include/openssl/ssl.h),)
+  ifneq ($(wildcard third_party/${openssl_fallback.extraction_dir}/libssl.a),)
+  HAS_EMBEDDED_OPENSSL_ALPN = third_party/${openssl_fallback.extraction_dir}
+  else ifeq ($(wildcard third_party/boringssl/include/openssl/ssl.h),)
   HAS_EMBEDDED_OPENSSL_ALPN = false
   else
-  HAS_EMBEDDED_OPENSSL_ALPN = true
+  CAN_COMPILE_EMBEDDED_OPENSSL ?= $(shell $(BORINGSSL_COMPILE_CHECK_CMD) 2> /dev/null && echo true || echo false)
+  HAS_EMBEDDED_OPENSSL_ALPN = $(CAN_COMPILE_EMBEDDED_OPENSSL)
   endif
 
   ifeq ($(wildcard third_party/zlib/zlib.h),)
@@ -498,8 +508,8 @@
   EMBED_OPENSSL ?= false
   NO_SECURE ?= false
   else # HAS_SYSTEM_OPENSSL_ALPN=false
-  ifeq ($(HAS_EMBEDDED_OPENSSL_ALPN),true)
-  EMBED_OPENSSL ?= true
+  ifneq ($(HAS_EMBEDDED_OPENSSL_ALPN),false)
+  EMBED_OPENSSL ?= $(HAS_EMBEDDED_OPENSSL_ALPN)
   NO_SECURE ?= false
   else # HAS_EMBEDDED_OPENSSL_ALPN=false
   ifeq ($(HAS_SYSTEM_OPENSSL_NPN),true)
@@ -520,6 +530,12 @@
   OPENSSL_MERGE_OBJS += $(LIBBORINGSSL_OBJS)
   # need to prefix these to ensure overriding system libraries
   CPPFLAGS := -Ithird_party/boringssl/include $(CPPFLAGS)
+  else ifneq ($(EMBED_OPENSSL),false)
+  OPENSSL_DEP += $(EMBED_OPENSSL)/libssl.a $(EMBED_OPENSSL)/libcrypto.a
+  OPENSSL_MERGE_LIBS += $(EMBED_OPENSSL)/libssl.a $(EMBED_OPENSSL)/libcrypto.a
+  OPENSSL_MERGE_OBJS += $(wildcard $(EMBED_OPENSSL)/grpc_obj/*.o)
+  # need to prefix these to ensure overriding system libraries
+  CPPFLAGS := -I$(EMBED_OPENSSL)/include $(CPPFLAGS)
   else # EMBED_OPENSSL=false
   ifeq ($(HAS_PKG_CONFIG),true)
   OPENSSL_PKG_CONFIG = true
@@ -706,8 +722,9 @@
   	@echo
   	@echo "DEPENDENCY ERROR"
   	@echo
-  	@echo "The target you are trying to run requires OpenSSL."
-  	@echo "Your system doesn't have it, and neither does the third_party directory."
+  	@echo "The target you are trying to run requires an OpenSSL implementation."
+  	@echo "Your system doesn't have one, and either the third_party directory"
+  	@echo "doesn't have it, or your compiler can't build BoringSSL."
   	@echo
   	@echo "Please consult INSTALL to get more information."
   	@echo
@@ -790,18 +807,22 @@
 
   static_c: pc_c pc_c_unsecure cache.mk pc_c_zookeeper\
   % for lib in libs:
+  % if 'Makefile' in lib.get('build_system', ['Makefile']):
   % if lib.build == 'all' and lib.language == 'c' and not lib.get('external_deps', None):
    $(LIBDIR)/$(CONFIG)/lib${lib.name}.a\
   % endif
+  % endif
   % endfor
    static_zookeeper_libs
 
 
   static_cxx: pc_cxx pc_cxx_unsecure cache.mk \
   % for lib in libs:
+  % if 'Makefile' in lib.get('build_system', ['Makefile']):
   % if lib.build == 'all' and lib.language == 'c++':
    $(LIBDIR)/$(CONFIG)/lib${lib.name}.a\
   % endif
+  % endif
   % endfor
 
 
@@ -809,40 +830,50 @@
 
   shared_c: pc_c pc_c_unsecure cache.mk pc_c_zookeeper\
   % for lib in libs:
+  % if 'Makefile' in lib.get('build_system', ['Makefile']):
   % if lib.build == 'all' and lib.language == 'c' and not lib.get('external_deps', None):
    $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)${lib.name}$(SHARED_VERSION).$(SHARED_EXT)\
   % endif
+  % endif
   % endfor
    shared_zookeeper_libs
 
   shared_cxx: pc_cxx pc_cxx_unsecure cache.mk\
   % for lib in libs:
+  % if 'Makefile' in lib.get('build_system', ['Makefile']):
   % if lib.build == 'all' and lib.language == 'c++':
    $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)${lib.name}$(SHARED_VERSION).$(SHARED_EXT)\
   % endif
+  % endif
   % endfor
 
 
   shared_csharp: shared_c \
   % for lib in libs:
+  % if 'Makefile' in lib.get('build_system', ['Makefile']):
   % if lib.build == 'all' and lib.language == 'csharp':
    $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)${lib.name}$(SHARED_VERSION).$(SHARED_EXT)\
   % endif
+  % endif
   % endfor
 
   ifeq ($(HAS_ZOOKEEPER),true)
   static_zookeeper_libs:\
   % for lib in libs:
+  % if 'Makefile' in lib.get('build_system', ['Makefile']):
   % if lib.build == 'all' and lib.language == 'c' and 'zookeeper' in lib.get('external_deps', []):
    $(LIBDIR)/$(CONFIG)/lib${lib.name}.a\
   % endif
+  % endif
   % endfor
 
   shared_zookeeper_libs:\
   % for lib in libs:
+  % if 'Makefile' in lib.get('build_system', ['Makefile']):
   % if lib.build == 'all' and lib.language == 'c' and 'zookeeper' in lib.get('external_deps', []):
    $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)${lib.name}$(SHARED_VERSION).$(SHARED_EXT)\
   % endif
+  % endif
   % endfor
 
   else
@@ -861,9 +892,11 @@
 
   privatelibs_c: \
   % for lib in libs:
+  % if 'Makefile' in lib.get('build_system', ['Makefile']):
   % if lib.build == 'private' and lib.language == 'c' and not lib.get('external_deps', None) and not lib.boringssl:
    $(LIBDIR)/$(CONFIG)/lib${lib.name}.a\
   % endif
+  % endif
   % endfor
 
   pc_c: $(LIBDIR)/$(CONFIG)/pkgconfig/grpc.pc
@@ -882,18 +915,22 @@
 
   privatelibs_cxx: \
   % for lib in libs:
+  % if 'Makefile' in lib.get('build_system', ['Makefile']):
   % if lib.build == 'private' and lib.language == 'c++' and not lib.get('external_deps', None):
    $(LIBDIR)/$(CONFIG)/lib${lib.name}.a\
   % endif
+  % endif
   % endfor
 
 
   ifeq ($(HAS_ZOOKEEPER),true)
   privatelibs_zookeeper: \
   % for lib in libs:
+  % if 'Makefile' in lib.get('build_system', ['Makefile']):
   % if lib.build == 'private' and lib.language == 'c++' and zookeeper in lib.get('external_deps', []):
    $(LIBDIR)/$(CONFIG)/lib${lib.name}.a\
   % endif
+  % endif
   % endfor
 
   else
@@ -1044,6 +1081,7 @@
   strip-static_c: static_c
   ifeq ($(CONFIG),opt)
   % for lib in libs:
+  % if 'Makefile' in lib.get('build_system', ['Makefile']):
   % if lib.language == "c":
   % if lib.build == "all":
   % if not lib.get('external_deps', None):
@@ -1052,9 +1090,11 @@
   % endif
   % endif
   % endif
+  % endif
   % endfor
   ifeq ($(HAS_ZOOKEEPER),true)
   % for lib in libs:
+  % if 'Makefile' in lib.get('build_system', ['Makefile']):
   % if lib.language == "c":
   % if lib.build == "all":
   % if 'zookeeper' in lib.get('external_deps', []):
@@ -1063,6 +1103,7 @@
   % endif
   % endif
   % endif
+  % endif
   % endfor
   endif
   endif
@@ -1070,18 +1111,21 @@
   strip-static_cxx: static_cxx
   ifeq ($(CONFIG),opt)
   % for lib in libs:
+  % if 'Makefile' in lib.get('build_system', ['Makefile']):
   % if lib.language == "c++":
   % if lib.build == "all":
   	$(E) "[STRIP]   Stripping lib${lib.name}.a"
   	$(Q) $(STRIP) $(LIBDIR)/$(CONFIG)/lib${lib.name}.a
   % endif
   % endif
+  % endif
   % endfor
   endif
 
   strip-shared_c: shared_c
   ifeq ($(CONFIG),opt)
   % for lib in libs:
+  % if 'Makefile' in lib.get('build_system', ['Makefile']):
   % if lib.language == "c":
   % if lib.build == "all":
   % if not lib.get('external_deps', None):
@@ -1090,9 +1134,11 @@
   % endif
   % endif
   % endif
+  % endif
   % endfor
   ifeq ($(HAS_ZOOKEEPER),true)
   % for lib in libs:
+  % if 'Makefile' in lib.get('build_system', ['Makefile']):
   % if lib.language == "c":
   % if lib.build == "all":
   % if 'zookeeper' in lib.get('external_deps', []):
@@ -1101,6 +1147,7 @@
   % endif
   % endif
   % endif
+  % endif
   % endfor
   endif
   endif
@@ -1108,24 +1155,28 @@
   strip-shared_cxx: shared_cxx
   ifeq ($(CONFIG),opt)
   % for lib in libs:
+  % if 'Makefile' in lib.get('build_system', ['Makefile']):
   % if lib.language == "c++":
   % if lib.build == "all":
   	$(E) "[STRIP]   Stripping $(SHARED_PREFIX)${lib.name}$(SHARED_VERSION).$(SHARED_EXT)"
   	$(Q) $(STRIP) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)${lib.name}$(SHARED_VERSION).$(SHARED_EXT)
   % endif
   % endif
+  % endif
   % endfor
   endif
 
   strip-shared_csharp: shared_csharp
   ifeq ($(CONFIG),opt)
   % for lib in libs:
+  % if 'Makefile' in lib.get('build_system', ['Makefile']):
   % if lib.language == "csharp":
   % if lib.build == "all":
   	$(E) "[STRIP]   Stripping $(SHARED_PREFIX)${lib.name}$(SHARED_VERSION).$(SHARED_EXT)"
   	$(Q) $(STRIP) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)${lib.name}$(SHARED_VERSION).$(SHARED_EXT)
   % endif
   % endif
+  % endif
   % endfor
   endif
 
@@ -1234,6 +1285,7 @@
 
   install-static_c: static_c strip-static_c install-pkg-config_c
   % for lib in libs:
+  % if 'Makefile' in lib.get('build_system', ['Makefile']):
   % if lib.language == "c":
   % if lib.build == "all":
   % if not lib.get('external_deps', None):
@@ -1243,9 +1295,11 @@
   % endif
   % endif
   % endif
+  % endif
   % endfor
   ifeq ($(HAS_ZOOKEEPER),true)
   % for lib in libs:
+  % if 'Makefile' in lib.get('build_system', ['Makefile']):
   % if lib.language == "c":
   % if lib.build == "all":
   % if 'zookeeper' in lib.get('external_deps', []):
@@ -1255,11 +1309,13 @@
   % endif
   % endif
   % endif
+  % endif
   % endfor
   endif
 
   install-static_cxx: static_cxx strip-static_cxx install-pkg-config_cxx
   % for lib in libs:
+  % if 'Makefile' in lib.get('build_system', ['Makefile']):
   % if lib.language == "c++":
   % if lib.build == "all":
   	$(E) "[INSTALL] Installing lib${lib.name}.a"
@@ -1267,10 +1323,12 @@
   	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/lib${lib.name}.a $(prefix)/lib/lib${lib.name}.a
   % endif
   % endif
+  % endif
   % endfor
 
   <%def name="install_shared(lang_filter)">\
   % for lib in libs:
+  % if 'Makefile' in lib.get('build_system', ['Makefile']):
   % if lib.language == lang_filter:
   % if lib.build == "all":
   % if not lib.get('external_deps', None):
@@ -1286,9 +1344,11 @@
   % endif
   % endif
   % endif
+  % endif
   % endfor
   ifeq ($(HAS_ZOOKEEPER),true)
   % for lib in libs:
+  % if 'Makefile' in lib.get('build_system', ['Makefile']):
   % if lib.language == lang_filter:
   % if lib.build == "all":
   % if 'zookeeper' in lib.get('external_deps', []):
@@ -1304,6 +1364,7 @@
   % endif
   % endif
   % endif
+  % endif
   % endfor
   endif
   ifneq ($(SYSTEM),MINGW32)
@@ -1383,7 +1444,9 @@
   # The various libraries
 
   % for lib in libs:
+  % if 'Makefile' in lib.get('build_system', ['Makefile']):
   ${makelib(lib)}
+  % endif
   % endfor
 
 
@@ -1498,7 +1561,7 @@
   % endif
 
   ifeq ($(SYSTEM),Darwin)
-  	$(Q) ranlib $(LIBDIR)/$(CONFIG)/lib${lib.name}.a
+  	$(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/lib${lib.name}.a
   endif
 
   <%
@@ -1800,3 +1863,9 @@
   strip_cxx strip-shared_cxx strip-static_cxx \
   dep_c dep_cxx bins_dep_c bins_dep_cxx \
   clean
+
+  .PHONY: printvars
+  printvars:
+  	@$(foreach V,$(sort $(.VARIABLES)),                 \
+  	  $(if $(filter-out environment% default automatic, \
+  	  $(origin $V)),$(warning $V=$($V) ($(value $V)))))
diff --git a/templates/README.md b/templates/README.md
index 6740972..eedc6e9 100644
--- a/templates/README.md
+++ b/templates/README.md
@@ -6,78 +6,92 @@
 
 So instead we decided to work the following way:
 
-* A build.json file at the root is the source of truth for listing all of the
-target and files needed to build grpc and its tests, as well as basic system
-dependencies description.
+* A `build.yaml` file at the root is the source of truth for listing all the
+targets and files needed to build grpc and its tests, as well as a basic system
+for dependency description.
 
 * Each project file (Makefile, Visual Studio project files, Bazel's BUILD) is
-a plain-text template that uses the build.json file to generate the final
-output file.
+a [YAML](http://yaml.org) file used by the `build.yaml` file to generate the
+final output file.
 
 This way we can maintain as many project system as we see fit, without having
 to manually maintain them when we add or remove new code to the repository.
 Only the structure of the project file is relevant to the template. The actual
 list of source code and targets isn't.
 
-We currently have template files for GNU Make, Visual Studio 2010 to 2015,
-and Bazel. In the future, we would like to expand to generating gyp or cmake
-project files (or potentially both), XCode project files, and an Android.mk
-file to be able to compile gRPC using Android's NDK.
+We currently have template files for GNU Make, Visual Studio 2013,
+[Bazel](http://bazel.io) and [gyp](https://gyp.gsrc.io/) (albeit only for
+Node.js). In the future, we
+would like to expand to also generate [cmake](https://cmake.org)
+project files, XCode project files, and an Android.mk file allowing to compile
+gRPC using Android's NDK.
 
 We'll gladly accept contribution that'd create additional project files
 using that system.
 
-# Structure of build.json
+# Structure of `build.yaml`
 
-The build.json file has the following structure:
+The `build.yaml` file has the following structure:
 
 ```
-{
-  "settings": { ... },   # global settings, such as version number
-  "filegroups": [ ... ], # groups of file that is automatically expanded
-  "libs": [ ... ],       # list of libraries to build
-  "targets": [ ... ],    # list of targets to build
-}
+settings:  # global settings, such as version number
+  ...
+filegroups:  # groups of files that are automatically expanded
+  ...
+libs:  # list of libraries to build
+  ...
+target:   # list of targets to build
+  ...
 ```
 
 The `filegroups` are helpful to re-use a subset of files in multiple targets.
 One `filegroups` entry has the following structure:
 
 ```
-{
-  "name": "arbitrary string", # the name of the filegroup
-  "public_headers": [ ... ],  # list of public headers defined in that filegroup
-  "headers": [ ... ],         # list of headers defined in that filegroup
-  "src": [ ... ],             # list of source files defined in that filegroup
-}
+- name: "arbitrary string", # the name of the filegroup
+  public_headers: # list of public headers defined in that filegroup
+  - ...
+  headers: # list of headers defined in that filegroup
+  - ...
+  src: # list of source files defined in that filegroup
+  - ...
 ```
 
-The `libs` array contains the list of all the libraries we describe. Some may be
+The `libs` collection contains the list of all the libraries we describe. Some may be
 helper libraries for the tests. Some may be installable libraries. Some may be
 helper libraries for installable binaries.
 
 The `targets` array contains the list of all the binary targets we describe. Some may
 be installable binaries.
 
-One `libs` or `targets` entry has the following structure:
+One `libs` or `targets` entry has the following structure (see below for
+details):
 
 ```
-{
-  "name": "arbitrary string", # the name of the library
-  "build": "build type",      # in which situation we want that library to be
-                              # built and potentially installed
-  "language": "...",          # the language tag; "c" or "c++"
-  "public_headers": [ ... ],  # list of public headers to install
-  "headers": [ ... ],         # list of headers used by that target
-  "src": [ ... ],             # list of files to compile
-  "secure": "...",            # "yes", "no" or "check"
-  "baselib": boolean,         # this is a low level library that has system
-                              # dependencies
-  "vs_project_guid: "...",    # Visual Studio's unique guid for that project
-  "filegroups": [ ... ],      # list of filegroups to merge to that project
-                              # note that this will be expanded automatically
-  "deps": [ ... ],            # list of libraries this target depends on
-}
+name: "arbitrary string", # the name of the library
+build: "build type",      # in which situation we want that library to be
+                          # built and potentially installed (see below).
+language: "...",          # the language tag; "c" or "c++"
+public_headers:           # list of public headers to install
+headers:                  # list of headers used by that target
+src:                      # list of files to compile
+secure: boolean,          # see below
+baselib: boolean,         # this is a low level library that has system
+                          # dependencies
+vs_project_guid: '{...}', # Visual Studio's unique guid for that project
+filegroups:               # list of filegroups to merge to that project
+                          # note that this will be expanded automatically
+deps:                     # list of libraries this target depends on
+deps_linkage: "..."       # "static"  or "dynamic". Used by the Makefile only to
+                          # determine the way dependencies are linkned. Defaults
+                          # to "dynamic".
+dll: "..."                # see below.
+dll_def: "..."            # Visual Studio's dll definition file.
+vs_props:                 # List of property sheets to attach to that project.
+vs_config_type: "..."     # DynamicLibrary/StaticLibrary. Used only when
+                          # creating a library. Specifies if we're building a
+                          # static library or a dll. Use in conjunction with `dll_def`.
+vs_packages:              # List of nuget packages this project depends on.
 ```
 
 ## The `"build"` tag
@@ -86,8 +100,9 @@
 
 * `"all"`: library to build on `"make all"`, and install on the system.
 * `"protoc"`: a protoc plugin to build on `"make all"` and install on the system.
-* `"priviate"`: a library to only build for tests.
+* `"private"`: a library to only build for tests.
 * `"test"`: a test binary to run on `"make test"`.
+* `"tool"`: a binary to be built upon `"make tools"`.
 
 All of the targets should always be present in the generated project file, if
 possible and applicable. But the build tag is what should group the targets
@@ -111,6 +126,18 @@
 on the `"language"` tag. OpenSSL and zlib are for `"c"` libraries, while
 protobuf is for `"c++"` ones.
 
+## The `"dll"` tag
+
+Used only by Visual Studio's project files. "true" means the project will be
+built with both static and dynamic runtimes. "false" means it'll only be built
+with static runtime. "only" means it'll only be built with the dll runtime.
+
+## The `"dll_def"` tag
+
+Specifies the visual studio's dll definition file. When creating a DLL, you
+sometimes (not always) need a def file (see grpc.def).
+
+
 # The template system
 
 We're currently using the [mako templates](http://www.makotemplates.org/)
diff --git a/templates/config.m4.template b/templates/config.m4.template
new file mode 100644
index 0000000..5847d45
--- /dev/null
+++ b/templates/config.m4.template
@@ -0,0 +1,59 @@
+%YAML 1.2
+--- |
+  PHP_ARG_ENABLE(grpc, whether to enable grpc support,
+  [  --enable-grpc           Enable grpc support])
+
+  if test "$PHP_GRPC" != "no"; then
+    dnl Write more examples of tests here...
+
+    dnl # --with-grpc -> add include path
+    PHP_ADD_INCLUDE(../../grpc/include)
+    PHP_ADD_INCLUDE(../../grpc/src/php/ext/grpc)
+    PHP_ADD_INCLUDE(../../grpc/third_party/boringssl/include)
+
+    LIBS="-lpthread $LIBS"
+
+    GRPC_SHARED_LIBADD="-lpthread $GRPC_SHARED_LIBADD"
+    PHP_ADD_LIBRARY(pthread)
+
+    PHP_ADD_LIBRARY(dl,,GRPC_SHARED_LIBADD)
+    PHP_ADD_LIBRARY(dl)
+
+    case $host in
+      *darwin*) ;;
+      *)
+        PHP_ADD_LIBRARY(rt,,GRPC_SHARED_LIBADD)
+        PHP_ADD_LIBRARY(rt)
+        ;;
+    esac
+
+    PHP_NEW_EXTENSION(grpc,
+      % for source in php_config_m4.src:
+      ${source} ${"\\"}
+      % endfor
+      % for lib in libs:
+      % if lib.name in php_config_m4.get('deps', []):
+      % for source in lib.src:
+      ${source} ${"\\"}
+      % endfor
+      % endif
+      % endfor
+      , $ext_shared, , -Wall -Werror ${"\\"}
+      -Wno-parentheses-equality -Wno-unused-value -std=c11 ${"\\"}
+      -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN ${"\\"}
+      -D_HAS_EXCEPTIONS=0 -DNOMINMAX)
+
+    PHP_ADD_BUILD_DIR($ext_builddir/src/php/ext/grpc)
+  <%
+    dirs = {}
+    for lib in libs:
+      if lib.name in php_config_m4.get('deps', []):
+        for source in lib.src:
+          dirs[source[:source.rfind('/')]] = 1
+    dirs = dirs.keys()
+    dirs.sort()
+  %>
+    % for dir in dirs:
+    PHP_ADD_BUILD_DIR($ext_builddir/${dir})
+    % endfor
+  fi
diff --git a/templates/package.xml.template b/templates/package.xml.template
new file mode 100644
index 0000000..d309bfd
--- /dev/null
+++ b/templates/package.xml.template
@@ -0,0 +1,174 @@
+%YAML 1.2
+--- |
+  <?xml version="1.0" encoding="UTF-8"?>
+  <package packagerversion="1.9.5" version="2.0" xmlns="http://pear.php.net/dtd/package-2.0" xmlns:tasks="http://pear.php.net/dtd/tasks-1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://pear.php.net/dtd/tasks-1.0 http://pear.php.net/dtd/tasks-1.0.xsd http://pear.php.net/dtd/package-2.0 http://pear.php.net/dtd/package-2.0.xsd">
+   <name>grpc</name>
+   <channel>pecl.php.net</channel>
+   <summary>A high performance, open source, general RPC framework that puts mobile and HTTP/2 first.</summary>
+   <description>Remote Procedure Calls (RPCs) provide a useful abstraction for building distributed applications and services. The libraries in this repository provide a concrete implementation of the gRPC protocol, layered over HTTP/2. These libraries enable communication between clients and servers using any combination of the supported languages.</description>
+   <lead>
+    <name>Stanley Cheung</name>
+    <user>stanleycheung</user>
+    <email>grpc-packages@google.com</email>
+    <active>yes</active>
+   </lead>
+   <date>2016-03-01</date>
+   <time>16:06:07</time>
+   <version>
+    <release>0.14.0</release>
+    <api>0.14.0</api>
+   </version>
+   <stability>
+    <release>beta</release>
+    <api>beta</api>
+   </stability>
+   <license>BSD</license>
+   <notes>
+  - Increase unit test code coverage #5225
+   </notes>
+   <contents>
+    <dir baseinstalldir="/" name="/">
+      <file baseinstalldir="/" name="config.m4" role="src" />
+      <file baseinstalldir="/" name="src/php/ext/grpc/CREDITS" role="src" />
+      <file baseinstalldir="/" name="src/php/ext/grpc/LICENSE" role="src" />
+      <file baseinstalldir="/" name="src/php/ext/grpc/README.md" role="src" />
+      % for source in php_config_m4.src + php_config_m4.headers:
+      <file baseinstalldir="/" name="${source}" role="src" />
+      % endfor
+      % for lib in libs:
+      % if lib.name in php_config_m4.get('deps', []):
+      % for source in lib.get('public_headers', []) + lib.headers + lib.src:
+      <file baseinstalldir="/" name="${source}" role="src" />
+      % endfor
+      % endif
+      % endfor
+    </dir>
+   </contents>
+   <dependencies>
+    <required>
+     <php>
+      <min>5.5.0</min>
+     </php>
+     <pearinstaller>
+      <min>1.4.0</min>
+     </pearinstaller>
+    </required>
+   </dependencies>
+   <providesextension>grpc</providesextension>
+   <extsrcrelease />
+   <changelog>
+    <release>
+     <version>
+      <release>0.5.0</release>
+      <api>0.5.0</api>
+     </version>
+     <stability>
+      <release>alpha</release>
+      <api>alpha</api>
+     </stability>
+     <date>2015-06-16</date>
+     <license>BSD</license>
+     <notes>
+  First alpha release
+     </notes>
+    </release>
+    <release>
+     <version>
+      <release>0.5.1</release>
+      <api>0.5.1</api>
+     </version>
+     <stability>
+      <release>alpha</release>
+      <api>alpha</api>
+     </stability>
+     <date>2015-07-09</date>
+     <license>BSD</license>
+     <notes>
+  Update to wrap gRPC C Core version 0.10.0
+     </notes>
+    </release>
+    <release>
+     <version>
+      <release>0.6.0</release>
+      <api>0.6.0</api>
+     </version>
+     <stability>
+      <release>beta</release>
+      <api>beta</api>
+     </stability>
+     <date>2015-09-24</date>
+     <license>BSD</license>
+     <notes>
+  - support per message compression disable
+  - expose per-call host override option
+  - expose connectivity API
+  - expose channel target and call peer
+  - add user-agent
+  - update to wrap gRPC C core library beta version 0.11.0
+     </notes>
+    </release>
+    <release>
+     <version>
+      <release>0.6.1</release>
+      <api>0.6.0</api>
+     </version>
+     <stability>
+      <release>beta</release>
+      <api>beta</api>
+     </stability>
+     <date>2015-10-21</date>
+     <license>BSD</license>
+     <notes>
+  - fixed undefined constant fatal error when run with apache/nginx #2275
+     </notes>
+    </release>
+    <release>
+     <version>
+      <release>0.7.0</release>
+      <api>0.7.0</api>
+     </version>
+     <stability>
+      <release>beta</release>
+      <api>beta</api>
+     </stability>
+     <date>2016-01-13</date>
+     <license>BSD</license>
+     <notes>
+  - Breaking change to Credentials class (removed) #3765
+  - Replaced by ChannelCredentials and CallCredentials class #3765
+  - New plugin based metadata auth API #4394
+  - Explicit ChannelCredentials::createInsecure() call
+     </notes>
+    </release>
+    <release>
+     <version>
+      <release>0.8.0</release>
+      <api>0.8.0</api>
+     </version>
+     <stability>
+      <release>beta</release>
+      <api>beta</api>
+     </stability>
+     <date>2016-02-24</date>
+     <license>BSD</license>
+     <notes>
+  - Simplify gRPC PHP installation #4517
+     </notes>
+    </release>
+    <release>
+     <version>
+      <release>0.14.0</release>
+      <api>0.14.0</api>
+     </version>
+     <stability>
+      <release>beta</release>
+      <api>beta</api>
+     </stability>
+     <date>2016-03-01</date>
+     <license>BSD</license>
+     <notes>
+  - Increase unit test code coverage #5225
+     </notes>
+    </release>
+   </changelog>
+  </package>
diff --git a/templates/src/csharp/build_packages.bat.template b/templates/src/csharp/build_packages.bat.template
index b855126..3245568 100644
--- a/templates/src/csharp/build_packages.bat.template
+++ b/templates/src/csharp/build_packages.bat.template
@@ -21,6 +21,14 @@
   xcopy /Y /I ..\..\architecture=x86,language=csharp,platform=macos\artifacts\* grpc.native.csharp\macosx_x86${"\\"}
   xcopy /Y /I ..\..\architecture=x64,language=csharp,platform=macos\artifacts\* grpc.native.csharp\macosx_x64${"\\"}
   
+  @rem Collect protoc artifacts built by the previous build step
+  xcopy /Y /I ..\..\architecture=x86,language=protoc,platform=windows\artifacts\* protoc_plugins\windows_x86${"\\"}
+  xcopy /Y /I ..\..\architecture=x64,language=protoc,platform=windows\artifacts\* protoc_plugins\windows_x64${"\\"}
+  xcopy /Y /I ..\..\architecture=x86,language=protoc,platform=linux\artifacts\* protoc_plugins\linux_x86${"\\"}
+  xcopy /Y /I ..\..\architecture=x64,language=protoc,platform=linux\artifacts\* protoc_plugins\linux_x64${"\\"}
+  xcopy /Y /I ..\..\architecture=x86,language=protoc,platform=macos\artifacts\* protoc_plugins\macosx_x86${"\\"}
+  xcopy /Y /I ..\..\architecture=x64,language=protoc,platform=macos\artifacts\* protoc_plugins\macosx_x64${"\\"}
+  
   @rem Fetch all dependencies
   %%NUGET% restore ..\..\vsprojects\grpc_csharp_ext.sln || goto :error
   %%NUGET% restore Grpc.sln || goto :error
@@ -29,24 +37,19 @@
   
   @call "%VS120COMNTOOLS%\..\..\vc\vcvarsall.bat" x86
   
-  @rem We won't use the native libraries from this step, but without this Grpc.sln will fail.  
+  @rem We won't use the native libraries from this step, but without this Grpc.sln will fail.
   msbuild ..\..\vsprojects\grpc_csharp_ext.sln /p:Configuration=Release /p:PlatformToolset=v120 || goto :error
   
   msbuild Grpc.sln /p:Configuration=ReleaseSigned || goto :error
   
   endlocal
   
-  @rem TODO(jtattermusch): re-enable protoc plugin building
-  @rem @call ..\..\vsprojects\build_plugins.bat || goto :error
-  
   %%NUGET% pack grpc.native.csharp\grpc.native.csharp.nuspec -Version %VERSION% || goto :error
   %%NUGET% pack Grpc.Auth\Grpc.Auth.nuspec -Symbols -Version %VERSION% || goto :error
   %%NUGET% pack Grpc.Core\Grpc.Core.nuspec -Symbols -Version %VERSION% || goto :error
   %%NUGET% pack Grpc.HealthCheck\Grpc.HealthCheck.nuspec -Symbols -Version %VERSION_WITH_BETA% -Properties ProtobufVersion=%PROTOBUF_VERSION% || goto :error
   %%NUGET% pack Grpc.nuspec -Version %VERSION% || goto :error
-  
-  @rem TODO(jtattermusch): re-enable building Grpc.Tools package
-  @rem %NUGET% pack Grpc.Tools.nuspec -Version %VERSION% || goto :error
+  %%NUGET% pack Grpc.Tools.nuspec -Version %VERSION% || goto :error
   
   @rem copy resulting nuget packages to artifacts directory
   xcopy /Y /I *.nupkg ..\..\artifacts${"\\"}
diff --git a/templates/tools/dockerfile/apt_get_basic.include b/templates/tools/dockerfile/apt_get_basic.include
index 9237e7d..547ce01 100644
--- a/templates/tools/dockerfile/apt_get_basic.include
+++ b/templates/tools/dockerfile/apt_get_basic.include
@@ -1,3 +1,4 @@
+<%page args="skip_golang=False"/>\
 # Install Git and basic packages.
 RUN apt-get update && apt-get install -y ${'\\'}
   autoconf ${'\\'}
@@ -9,7 +10,9 @@
   gcc ${'\\'}
   gcc-multilib ${'\\'}
   git ${'\\'}
+% if not skip_golang:
   golang ${'\\'}
+% endif
   gyp ${'\\'}
   lcov ${'\\'}
   libc6 ${'\\'}
diff --git a/templates/tools/dockerfile/run_tests_addons.include b/templates/tools/dockerfile/run_tests_addons.include
index 27ac67f..30d22be 100644
--- a/templates/tools/dockerfile/run_tests_addons.include
+++ b/templates/tools/dockerfile/run_tests_addons.include
@@ -1,7 +1,10 @@
+<%page args="skip_zookeeper=False"/>\
 <%include file="ccache_setup.include"/>
+% if not skip_zookeeper:
 #======================
 # Zookeeper dependencies
 # TODO(jtattermusch): is zookeeper still needed?
 RUN apt-get install -y libzookeeper-mt-dev
+% endif
 
 RUN mkdir /var/local/jenkins
diff --git a/templates/tools/dockerfile/test/cxx_squeeze_x64/Dockerfile.template b/templates/tools/dockerfile/test/cxx_squeeze_x64/Dockerfile.template
new file mode 100644
index 0000000..49371aa
--- /dev/null
+++ b/templates/tools/dockerfile/test/cxx_squeeze_x64/Dockerfile.template
@@ -0,0 +1,48 @@
+%YAML 1.2
+--- |
+  # Copyright 2016, Google Inc.
+  # All rights reserved.
+  #
+  # Redistribution and use in source and binary forms, with or without
+  # modification, are permitted provided that the following conditions are
+  # met:
+  #
+  #     * Redistributions of source code must retain the above copyright
+  # notice, this list of conditions and the following disclaimer.
+  #     * Redistributions in binary form must reproduce the above
+  # copyright notice, this list of conditions and the following disclaimer
+  # in the documentation and/or other materials provided with the
+  # distribution.
+  #     * Neither the name of Google Inc. nor the names of its
+  # contributors may be used to endorse or promote products derived from
+  # this software without specific prior written permission.
+  #
+  # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+  # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+  # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+  # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+  # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+  # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+  # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+  # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+  # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+  # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+  # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+  FROM debian:squeeze
+
+  <%include file="../../apt_get_basic.include" args="skip_golang=True"/>
+
+  # libgflags-dev is not available on squeezy
+  RUN apt-get update && apt-get -y install libgtest-dev libc++-dev clang && apt-get clean
+
+  RUN apt-get update && apt-get -y install python-pip && apt-get clean
+  RUN pip install argparse
+
+  RUN wget ${openssl_fallback.base_uri + openssl_fallback.tarball}
+
+  ENV POST_GIT_STEP tools/dockerfile/test/cxx_squeeze_x64/post-git-setup.sh
+
+  <%include file="../../run_tests_addons.include" args="skip_zookeeper=True"/>
+  # Define the default command.
+  CMD ["bash"]
diff --git a/templates/tools/dockerfile/test/cxx_squeeze_x64/post-git-setup.sh.template b/templates/tools/dockerfile/test/cxx_squeeze_x64/post-git-setup.sh.template
new file mode 100644
index 0000000..b885101
--- /dev/null
+++ b/templates/tools/dockerfile/test/cxx_squeeze_x64/post-git-setup.sh.template
@@ -0,0 +1,37 @@
+%YAML 1.2
+--- |
+  #!/bin/bash
+  # Copyright 2016, Google Inc.
+  # All rights reserved.
+  #
+  # Redistribution and use in source and binary forms, with or without
+  # modification, are permitted provided that the following conditions are
+  # met:
+  #
+  #     * Redistributions of source code must retain the above copyright
+  # notice, this list of conditions and the following disclaimer.
+  #     * Redistributions in binary form must reproduce the above
+  # copyright notice, this list of conditions and the following disclaimer
+  # in the documentation and/or other materials provided with the
+  # distribution.
+  #     * Neither the name of Google Inc. nor the names of its
+  # contributors may be used to endorse or promote products derived from
+  # this software without specific prior written permission.
+  #
+  # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+  # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+  # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+  # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+  # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+  # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+  # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+  # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+  # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+  # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+  # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+  set -ex
+
+  cd /var/local/git/grpc
+  cp /${openssl_fallback.tarball} third_party
+  ./tools/openssl/use_openssl.sh
diff --git a/templates/tools/dockerfile/test/cxx_ubuntu1604_x64/Dockerfile.template b/templates/tools/dockerfile/test/cxx_ubuntu1604_x64/Dockerfile.template
new file mode 100644
index 0000000..6b30274
--- /dev/null
+++ b/templates/tools/dockerfile/test/cxx_ubuntu1604_x64/Dockerfile.template
@@ -0,0 +1,39 @@
+%YAML 1.2
+--- |
+  # Copyright 2015-2016, Google Inc.
+  # All rights reserved.
+  #
+  # Redistribution and use in source and binary forms, with or without
+  # modification, are permitted provided that the following conditions are
+  # met:
+  #
+  #     * Redistributions of source code must retain the above copyright
+  # notice, this list of conditions and the following disclaimer.
+  #     * Redistributions in binary form must reproduce the above
+  # copyright notice, this list of conditions and the following disclaimer
+  # in the documentation and/or other materials provided with the
+  # distribution.
+  #     * Neither the name of Google Inc. nor the names of its
+  # contributors may be used to endorse or promote products derived from
+  # this software without specific prior written permission.
+  #
+  # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+  # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+  # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+  # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+  # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+  # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+  # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+  # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+  # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+  # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+  # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+  
+  FROM ubuntu:16.04
+  
+  <%include file="../../apt_get_basic.include"/>
+  <%include file="../../cxx_deps.include"/>
+  <%include file="../../run_tests_addons.include"/>
+  # Define the default command.
+  CMD ["bash"]
+  
\ No newline at end of file
diff --git a/templates/tools/openssl/use_openssl.sh.template b/templates/tools/openssl/use_openssl.sh.template
new file mode 100644
index 0000000..5fb3771
--- /dev/null
+++ b/templates/tools/openssl/use_openssl.sh.template
@@ -0,0 +1,63 @@
+%YAML 1.2
+--- |
+  #!/bin/bash
+
+  # Copyright 2015-2016, Google Inc.
+  # All rights reserved.
+  #
+  # Redistribution and use in source and binary forms, with or without
+  # modification, are permitted provided that the following conditions are
+  # met:
+  #
+  #     * Redistributions of source code must retain the above copyright
+  # notice, this list of conditions and the following disclaimer.
+  #     * Redistributions in binary form must reproduce the above
+  # copyright notice, this list of conditions and the following disclaimer
+  # in the documentation and/or other materials provided with the
+  # distribution.
+  #     * Neither the name of Google Inc. nor the names of its
+  # contributors may be used to endorse or promote products derived from
+  # this software without specific prior written permission.
+  #
+  # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+  # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+  # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+  # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+  # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+  # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+  # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+  # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+  # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+  # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+  # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+  set -ex
+
+  cd $(dirname $0)/../..
+  set root=`pwd`
+  CC=${"${CC:-cc}"}
+
+  # allow openssl to be pre-downloaded
+  if [ ! -e third_party/${openssl_fallback.tarball} ]
+  then
+    echo "Downloading ${openssl_fallback.base_uri + openssl_fallback.tarball} to third_party/${openssl_fallback.tarball}"
+    wget ${openssl_fallback.base_uri + openssl_fallback.tarball} -O third_party/${openssl_fallback.tarball}
+  fi
+
+  # clean openssl directory
+  rm -rf third_party/${openssl_fallback.extraction_dir}
+
+  # extract archive
+  cd third_party
+  tar xfz ${openssl_fallback.tarball}
+
+  # build openssl
+  cd ${openssl_fallback.extraction_dir}
+  CC="$CC -fPIC -fvisibility=hidden" ./config no-asm
+  make
+
+  # generate the 'grpc_obj' directory needed by the makefile
+  mkdir grpc_obj
+  cd grpc_obj
+  ar x ../libcrypto.a
+  ar x ../libssl.a
diff --git a/templates/tools/run_tests/sources_and_headers.json.template b/templates/tools/run_tests/sources_and_headers.json.template
index 0480277..18b9bc2 100644
--- a/templates/tools/run_tests/sources_and_headers.json.template
+++ b/templates/tools/run_tests/sources_and_headers.json.template
@@ -3,34 +3,48 @@
   <%!
   import json
   import os
-  
+
   def proto_headers(src):
+    out = []
+    for f in src:
+      name, ext = os.path.splitext(f)
+      if ext == '.proto':
+        out.extend(fmt % name for fmt in ['%s.grpc.pb.h', '%s.pb.h'])
+    return out
+
+  def all_targets(targets, libs):
+    for tgt in targets:
+      yield ('target', tgt)
+    for tgt in libs:
+      yield ('lib', tgt)
+
+  def no_protos_filter(src):
+  	return os.path.splitext(src)[1] != '.proto'
+
+  def no_third_party_filter(src):
+  	return not src.startswith('third_party/')
+
+  def filter_srcs(srcs, filters):
   	out = []
-  	for f in src:
-  		name, ext = os.path.splitext(f)
-  		if ext == '.proto':
-  			out.extend(fmt % name for fmt in ['%s.grpc.pb.h', '%s.pb.h'])
-  	return out
-  
-  def no_protos(src):
-  	out = []
-  	for f in src:
-  		if os.path.splitext(f)[1] != '.proto':
-  			out.append(f)
+  	for s in srcs:
+  		filter_passes = (f(s) for f in filters)
+  		if all(filter_passes):
+  			out.append(s)
   	return out
   %>
-  
+
   ${json.dumps([{"name": tgt.name,
+                 "type": typ,
                  "language": tgt.language,
+                 "third_party": tgt.boringssl or tgt.zlib,
                  "src": sorted(
-                     no_protos(tgt.src) + 
-                     tgt.get('public_headers', []) + 
-                     tgt.get('headers', [])),
+                     filter_srcs(tgt.src, (no_protos_filter, no_third_party_filter)) +
+                     filter_srcs(tgt.get('public_headers', []), (no_protos_filter, no_third_party_filter)) +
+                     filter_srcs(tgt.get('headers', []), (no_third_party_filter,))),
                  "headers": sorted(
-                     tgt.get('public_headers', []) + 
-                     tgt.get('headers', []) + 
+                     tgt.get('public_headers', []) +
+                     tgt.get('headers', []) +
                      proto_headers(tgt.src)),
                  "deps": sorted(tgt.get('deps', []))}
-                for tgt in (targets + libs)
-                if not tgt.boringssl and not tgt.zlib],
+                for typ, tgt in all_targets(targets, libs)],
                sort_keys=True, indent=2)}
diff --git a/templates/tools/run_tests/tests.json.template b/templates/tools/run_tests/tests.json.template
index 9a84783..5690874 100644
--- a/templates/tools/run_tests/tests.json.template
+++ b/templates/tools/run_tests/tests.json.template
@@ -3,11 +3,12 @@
   <%!
   import json
   %>
-  
+
   ${json.dumps([{"name": tgt.name,
                  "language": tgt.language,
                  "platforms": tgt.platforms,
                  "ci_platforms": tgt.ci_platforms,
+                 "gtest": tgt.gtest,
                  "exclude_configs": tgt.get("exclude_configs", []),
                  "args": [],
                  "flaky": tgt.flaky,
diff --git a/templates/vsprojects/protoc.props.template b/templates/vsprojects/protoc.props.template
index a869005..ced6028 100644
--- a/templates/vsprojects/protoc.props.template
+++ b/templates/vsprojects/protoc.props.template
@@ -4,6 +4,9 @@
   <PropertyGroup Label="UserMacros" />

   <PropertyGroup />

   <ItemDefinitionGroup>

+    <ClCompile>

+      <DisableSpecificWarnings>4244;4267;%(DisableSpecificWarnings)</DisableSpecificWarnings>

+    </ClCompile>

     <Link>

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

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

diff --git a/templates/vsprojects/vcxproj.filters_defs.include b/templates/vsprojects/vcxproj.filters_defs.include
index 7e2fbac..e7df8db 100644
--- a/templates/vsprojects/vcxproj.filters_defs.include
+++ b/templates/vsprojects/vcxproj.filters_defs.include
@@ -23,6 +23,11 @@
     % endfor
   </ItemGroup>
   % endif
+  % if project.get('dll_def', None):
+  <ItemGroup>
+    <None Include="${get_repo_root(project)}\${to_windows_path(project.dll_def)}" />
+  </ItemGroup>
+  % endif
   % if project.get('public_headers',[]):
   <ItemGroup>
     % for public_header in project.public_headers:
diff --git a/templates/vsprojects/vcxproj_defs.include b/templates/vsprojects/vcxproj_defs.include
index ad1d471..72a077f 100644
--- a/templates/vsprojects/vcxproj_defs.include
+++ b/templates/vsprojects/vcxproj_defs.include
@@ -2,6 +2,9 @@
 <%def name="to_windows_path(path)">${path.replace('/','\\')}</%def>\
 <%def name="get_subsystem(is_library)">${'Windows' if is_library else 'Console'}</%def>\
 <%def name="item_definition_group(project, target, debug, dll, _64bit)">\
+<%
+  repo_root = '$(SolutionDir)\..'
+%>\
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='${'%s%s|%s' % ('Debug' if debug else 'Release', '-DLL' if dll else '', 'x64' if _64bit else 'Win32')}'">
     <ClCompile>
       <PrecompiledHeader>NotUsing</PrecompiledHeader>
@@ -23,6 +26,12 @@
       <SubSystem>${get_subsystem(project.is_library)}</SubSystem>
       <GenerateDebugInformation Condition="!$(Jenkins)">true</GenerateDebugInformation>
       <GenerateDebugInformation Condition="$(Jenkins)">false</GenerateDebugInformation>
+% if project.get("noentry", False):
+      <NoEntryPoint>true</NoEntryPoint>
+% endif
+% if project.get("dll_def", None):
+      <ModuleDefinitionFile>${repo_root}\${to_windows_path(project.dll_def)}</ModuleDefinitionFile>
+% endif
 % if not debug:
       <EnableCOMDATFolding>true</EnableCOMDATFolding>
       <OptimizeReferences>true</OptimizeReferences>
@@ -194,6 +203,11 @@
     % endfor
   </ItemGroup>
   % endif
+  % if project.get('dll_def', None):
+  <ItemGroup>
+    <None Include="${repo_root}\${to_windows_path(project.dll_def)}" />
+  </ItemGroup>
+  % endif
   % if project.get('src',[]):
   <ItemGroup>
     % for src_name in project.src:
diff --git a/test/cpp/qps/timer.h b/test/build/boringssl.c
similarity index 82%
copy from test/cpp/qps/timer.h
copy to test/build/boringssl.c
index d1aee1a..a31d4bf 100644
--- a/test/cpp/qps/timer.h
+++ b/test/build/boringssl.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,27 +31,21 @@
  *
  */
 
-#ifndef TEST_QPS_TIMER_H
-#define TEST_QPS_TIMER_H
+// Check that boringssl is going to compile
 
-class Timer {
- public:
-  Timer();
+#include <stdio.h>
+#include <unistd.h>
 
-  struct Result {
-    double wall;
-    double user;
-    double system;
+// boringssl uses anonymous unions
+struct foo {
+  union {
+    int a;
+    int b;
   };
-
-  Result Mark() const;
-
-  static double Now();
-
- private:
-  static Result Sample();
-
-  const Result start_;
 };
 
-#endif  // TEST_QPS_TIMER_H
+int main(void) {
+  const char *close = "this should not shadow";
+  printf("%s\n", close);
+  return 0;
+}
diff --git a/test/core/bad_ssl/server.h b/test/build/shadow.c
similarity index 84%
copy from test/core/bad_ssl/server.h
copy to test/build/shadow.c
index 8ec7755..51d4f9e 100644
--- a/test/core/bad_ssl/server.h
+++ b/test/build/shadow.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,12 +31,13 @@
  *
  */
 
-#ifndef GRPC_TEST_CORE_BAD_SSL_SERVER_H
-#define GRPC_TEST_CORE_BAD_SSL_SERVER_H
+// Check that boringssl is going to compile
 
-#include <grpc/grpc.h>
+#include <stdio.h>
+#include <unistd.h>
 
-const char *bad_ssl_addr(int argc, char **argv);
-void bad_ssl_run(grpc_server *server);
-
-#endif /* GRPC_TEST_CORE_BAD_SSL_SERVER_H */
+int main(void) {
+  const char *close = "this should not shadow";
+  printf("%s\n", close);
+  return 0;
+}
diff --git a/test/core/bad_ssl/gen_build_yaml.py b/test/core/bad_ssl/gen_build_yaml.py
index cc097a8..e2a3feb 100755
--- a/test/core/bad_ssl/gen_build_yaml.py
+++ b/test/core/bad_ssl/gen_build_yaml.py
@@ -52,8 +52,8 @@
               'name': 'bad_ssl_test_server',
               'build': 'private',
               'language': 'c',
-              'src': ['test/core/bad_ssl/server.c'],
-              'headers': ['test/core/bad_ssl/server.h'],
+              'src': ['test/core/bad_ssl/server_common.c'],
+              'headers': ['test/core/bad_ssl/server_common.h'],
               'vs_proj_dir': 'test',
               'platforms': ['linux', 'posix', 'mac'],
               'deps': [
diff --git a/test/core/bad_ssl/server.c b/test/core/bad_ssl/server_common.c
similarity index 97%
rename from test/core/bad_ssl/server.c
rename to test/core/bad_ssl/server_common.c
index 6113d36..cde844a 100644
--- a/test/core/bad_ssl/server.c
+++ b/test/core/bad_ssl/server_common.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -35,7 +35,7 @@
 #include <grpc/support/log.h>
 #include <signal.h>
 
-#include "test/core/bad_ssl/server.h"
+#include "test/core/bad_ssl/server_common.h"
 #include "test/core/util/test_config.h"
 
 /* Common server implementation details for all servers in servers/.
diff --git a/test/core/bad_ssl/server.h b/test/core/bad_ssl/server_common.h
similarity index 97%
rename from test/core/bad_ssl/server.h
rename to test/core/bad_ssl/server_common.h
index 8ec7755..2566c25 100644
--- a/test/core/bad_ssl/server.h
+++ b/test/core/bad_ssl/server_common.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/test/core/bad_ssl/servers/alpn.c b/test/core/bad_ssl/servers/alpn.c
index 7d70690..c8cc83b 100644
--- a/test/core/bad_ssl/servers/alpn.c
+++ b/test/core/bad_ssl/servers/alpn.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -39,7 +39,7 @@
 #include <grpc/support/useful.h>
 
 #include "src/core/transport/chttp2/alpn.h"
-#include "test/core/bad_ssl/server.h"
+#include "test/core/bad_ssl/server_common.h"
 #include "test/core/end2end/data/ssl_test_data.h"
 
 /* This test starts a server that is configured to advertise (via alpn and npn)
diff --git a/test/core/bad_ssl/servers/cert.c b/test/core/bad_ssl/servers/cert.c
index d67a6ca..4edef50 100644
--- a/test/core/bad_ssl/servers/cert.c
+++ b/test/core/bad_ssl/servers/cert.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -38,9 +38,9 @@
 #include <grpc/support/log.h>
 #include <grpc/support/useful.h>
 
-#include "src/core/support/file.h"
+#include "src/core/support/load_file.h"
 
-#include "test/core/bad_ssl/server.h"
+#include "test/core/bad_ssl/server_common.h"
 #include "test/core/end2end/data/ssl_test_data.h"
 
 /* This server will present an untrusted cert to the connecting client,
diff --git a/test/core/census/context_test.c b/test/core/census/context_test.c
index 63e7103..ad4c337 100644
--- a/test/core/census/context_test.c
+++ b/test/core/census/context_test.c
@@ -42,60 +42,48 @@
 #include <string.h>
 #include "test/core/util/test_config.h"
 
-static uint8_t one_byte_val = 7;
-static uint32_t four_byte_val = 0x12345678;
-static uint64_t eight_byte_val = 0x1234567890abcdef;
-
-// A set of tags Used to create a basic context for testing. Each tag has a
-// unique set of flags. Note that replace_add_delete_test() relies on specific
-// offsets into this array - if you add or delete entries, you will also need
-// to change the test.
+// A set of tags Used to create a basic context for testing. Note that
+// replace_add_delete_test() relies on specific offsets into this array - if
+// you add or delete entries, you will also need to change the test.
 #define BASIC_TAG_COUNT 8
 static census_tag basic_tags[BASIC_TAG_COUNT] = {
-    /* 0 */ {"key0", "printable", 10, 0},
-    /* 1 */ {"k1", "a", 2, CENSUS_TAG_PROPAGATE},
-    /* 2 */ {"k2", "longer printable string", 24, CENSUS_TAG_STATS},
-    /* 3 */ {"key_three", (char *)&one_byte_val, 1, CENSUS_TAG_BINARY},
-    /* 4 */ {"really_long_key_4", "random", 7,
+    /* 0 */ {"key0", "tag value", 0},
+    /* 1 */ {"k1", "a", CENSUS_TAG_PROPAGATE},
+    /* 2 */ {"k2", "a longer tag value supercalifragilisticexpialiadocious",
+             CENSUS_TAG_STATS},
+    /* 3 */ {"key_three", "", 0},
+    /* 4 */ {"a_really_really_really_really_long_key_4", "random",
              CENSUS_TAG_PROPAGATE | CENSUS_TAG_STATS},
-    /* 5 */ {"k5", (char *)&four_byte_val, 4,
-             CENSUS_TAG_PROPAGATE | CENSUS_TAG_BINARY},
-    /* 6 */ {"k6", (char *)&eight_byte_val, 8,
-             CENSUS_TAG_STATS | CENSUS_TAG_BINARY},
-    /* 7 */ {"k7", (char *)&four_byte_val, 4,
-             CENSUS_TAG_PROPAGATE | CENSUS_TAG_STATS | CENSUS_TAG_BINARY}};
+    /* 5 */ {"k5", "v5", CENSUS_TAG_PROPAGATE},
+    /* 6 */ {"k6", "v6", CENSUS_TAG_STATS},
+    /* 7 */ {"k7", "v7", CENSUS_TAG_PROPAGATE | CENSUS_TAG_STATS}};
 
 // Set of tags used to modify the basic context. Note that
 // replace_add_delete_test() relies on specific offsets into this array - if
 // you add or delete entries, you will also need to change the test. Other
 // tests that rely on specific instances have XXX_XXX_OFFSET definitions (also
 // change the defines below if you add/delete entires).
-#define MODIFY_TAG_COUNT 11
+#define MODIFY_TAG_COUNT 10
 static census_tag modify_tags[MODIFY_TAG_COUNT] = {
 #define REPLACE_VALUE_OFFSET 0
-    /* 0 */ {"key0", "replace printable", 18, 0},  // replaces tag value only
+    /* 0 */ {"key0", "replace key0", 0},  // replaces tag value only
 #define ADD_TAG_OFFSET 1
-    /* 1 */ {"new_key", "xyzzy", 6, CENSUS_TAG_STATS},  // new tag
+    /* 1 */ {"new_key", "xyzzy", CENSUS_TAG_STATS},  // new tag
 #define DELETE_TAG_OFFSET 2
-    /* 2 */ {"k5", NULL, 5,
-             0},  // should delete tag, despite bogus value length
-    /* 3 */ {"k6", "foo", 0, 0},  // should delete tag, despite bogus value
-    /* 4 */ {"k6", "foo", 0, 0},  // try deleting already-deleted tag
-    /* 5 */ {"non-existent", NULL, 0, 0},  // another non-existent tag
-#define REPLACE_FLAG_OFFSET 6
-    /* 6 */ {"k1", "a", 2, 0},                   // change flags only
-    /* 7 */ {"k7", "bar", 4, CENSUS_TAG_STATS},  // change flags and value
-    /* 8 */ {"k2", (char *)&eight_byte_val, 8,
-             CENSUS_TAG_BINARY | CENSUS_TAG_PROPAGATE},  // more flags change
-                                                         // non-binary -> binary
-    /* 9 */ {"k6", "bar", 4, 0},  // add back tag, with different value
-    /* 10 */ {"foo", "bar", 4, CENSUS_TAG_PROPAGATE},  // another new tag
+    /* 2 */ {"k5", NULL, 0},            // should delete tag
+    /* 3 */ {"k5", NULL, 0},            // try deleting already-deleted tag
+    /* 4 */ {"non-existent", NULL, 0},  // delete non-existent tag
+#define REPLACE_FLAG_OFFSET 5
+    /* 5 */ {"k1", "a", 0},                    // change flags only
+    /* 6 */ {"k7", "bar", CENSUS_TAG_STATS},   // change flags and value
+    /* 7 */ {"k2", "", CENSUS_TAG_PROPAGATE},  // more value and flags change
+    /* 8 */ {"k5", "bar", 0},  // add back tag, with different value
+    /* 9 */ {"foo", "bar", CENSUS_TAG_PROPAGATE},  // another new tag
 };
 
 // Utility function to compare tags. Returns true if all fields match.
 static bool compare_tag(const census_tag *t1, const census_tag *t2) {
-  return (strcmp(t1->key, t2->key) == 0 && t1->value_len == t2->value_len &&
-          memcmp(t1->value, t2->value, t1->value_len) == 0 &&
+  return (strcmp(t1->key, t2->key) == 0 && strcmp(t1->value, t2->value) == 0 &&
           t1->flags == t2->flags);
 }
 
@@ -111,7 +99,7 @@
   struct census_context *context = census_context_create(NULL, NULL, 0, NULL);
   GPR_ASSERT(context != NULL);
   const census_context_status *status = census_context_get_status(context);
-  census_context_status expected = {0, 0, 0, 0, 0, 0, 0, 0};
+  census_context_status expected = {0, 0, 0, 0, 0, 0, 0};
   GPR_ASSERT(memcmp(status, &expected, sizeof(expected)) == 0);
   census_context_destroy(context);
 }
@@ -121,7 +109,7 @@
   const census_context_status *status;
   struct census_context *context =
       census_context_create(NULL, basic_tags, BASIC_TAG_COUNT, &status);
-  census_context_status expected = {2, 2, 4, 0, 8, 0, 0, 0};
+  census_context_status expected = {4, 4, 0, 8, 0, 0, 0};
   GPR_ASSERT(memcmp(status, &expected, sizeof(expected)) == 0);
   census_context_iterator it;
   census_context_initialize_iterator(context, &it);
@@ -161,15 +149,18 @@
   memset(key, 'k', 299);
   key[299] = 0;
   char value[300];
-  memset(value, 'v', 300);
-  census_tag tag = {key, value, 3, CENSUS_TAG_BINARY};
+  memset(value, 'v', 299);
+  value[299] = 0;
+  census_tag tag = {key, value, 0};
   // long keys, short value. Key lengths (including terminator) should be
   // <= 255 (CENSUS_MAX_TAG_KV_LEN)
+  value[3] = 0;
+  GPR_ASSERT(strlen(value) == 3);
   GPR_ASSERT(strlen(key) == 299);
   const census_context_status *status;
   struct census_context *context =
       census_context_create(NULL, &tag, 1, &status);
-  census_context_status expected = {0, 0, 0, 0, 0, 0, 1, 0};
+  census_context_status expected = {0, 0, 0, 0, 0, 1, 0};
   GPR_ASSERT(memcmp(status, &expected, sizeof(expected)) == 0);
   census_context_destroy(context);
   key[CENSUS_MAX_TAG_KV_LEN] = 0;
@@ -180,24 +171,44 @@
   key[CENSUS_MAX_TAG_KV_LEN - 1] = 0;
   GPR_ASSERT(strlen(key) == CENSUS_MAX_TAG_KV_LEN - 1);
   context = census_context_create(NULL, &tag, 1, &status);
-  census_context_status expected2 = {0, 0, 1, 0, 1, 0, 0, 0};
+  census_context_status expected2 = {0, 1, 0, 1, 0, 0, 0};
   GPR_ASSERT(memcmp(status, &expected2, sizeof(expected2)) == 0);
   census_context_destroy(context);
   // now try with long values
-  tag.value_len = 300;
+  value[3] = 'v';
+  GPR_ASSERT(strlen(value) == 299);
   context = census_context_create(NULL, &tag, 1, &status);
   GPR_ASSERT(memcmp(status, &expected, sizeof(expected)) == 0);
   census_context_destroy(context);
-  tag.value_len = CENSUS_MAX_TAG_KV_LEN + 1;
+  value[CENSUS_MAX_TAG_KV_LEN] = 0;
+  GPR_ASSERT(strlen(value) == CENSUS_MAX_TAG_KV_LEN);
   context = census_context_create(NULL, &tag, 1, &status);
   GPR_ASSERT(memcmp(status, &expected, sizeof(expected)) == 0);
   census_context_destroy(context);
-  tag.value_len = CENSUS_MAX_TAG_KV_LEN;
+  value[CENSUS_MAX_TAG_KV_LEN - 1] = 0;
+  GPR_ASSERT(strlen(value) == CENSUS_MAX_TAG_KV_LEN - 1);
   context = census_context_create(NULL, &tag, 1, &status);
   GPR_ASSERT(memcmp(status, &expected2, sizeof(expected2)) == 0);
   census_context_destroy(context);
   // 0 length key.
   key[0] = 0;
+  GPR_ASSERT(strlen(key) == 0);
+  context = census_context_create(NULL, &tag, 1, &status);
+  GPR_ASSERT(memcmp(status, &expected, sizeof(expected)) == 0);
+  census_context_destroy(context);
+  // invalid key character
+  key[0] = 31;  // 32 (' ') is the first valid character value
+  key[1] = 0;
+  GPR_ASSERT(strlen(key) == 1);
+  context = census_context_create(NULL, &tag, 1, &status);
+  GPR_ASSERT(memcmp(status, &expected, sizeof(expected)) == 0);
+  census_context_destroy(context);
+  // invalid value character
+  key[0] = ' ';
+  value[5] = 127;  // 127 (DEL) is ('~' + 1)
+  value[8] = 0;
+  GPR_ASSERT(strlen(key) == 1);
+  GPR_ASSERT(strlen(value) == 8);
   context = census_context_create(NULL, &tag, 1, &status);
   GPR_ASSERT(memcmp(status, &expected, sizeof(expected)) == 0);
   census_context_destroy(context);
@@ -210,7 +221,7 @@
   const census_context_status *status;
   struct census_context *context2 =
       census_context_create(context, NULL, 0, &status);
-  census_context_status expected = {2, 2, 4, 0, 0, 0, 0, 0};
+  census_context_status expected = {4, 4, 0, 0, 0, 0, 0};
   GPR_ASSERT(memcmp(status, &expected, sizeof(expected)) == 0);
   for (int i = 0; i < BASIC_TAG_COUNT; i++) {
     census_tag tag;
@@ -228,7 +239,7 @@
   const census_context_status *status;
   struct census_context *context2 = census_context_create(
       context, modify_tags + REPLACE_VALUE_OFFSET, 1, &status);
-  census_context_status expected = {2, 2, 4, 0, 0, 1, 0, 0};
+  census_context_status expected = {4, 4, 0, 0, 1, 0, 0};
   GPR_ASSERT(memcmp(status, &expected, sizeof(expected)) == 0);
   census_tag tag;
   GPR_ASSERT(census_context_get_tag(
@@ -245,7 +256,7 @@
   const census_context_status *status;
   struct census_context *context2 = census_context_create(
       context, modify_tags + REPLACE_FLAG_OFFSET, 1, &status);
-  census_context_status expected = {1, 2, 5, 0, 0, 1, 0, 0};
+  census_context_status expected = {3, 5, 0, 0, 1, 0, 0};
   GPR_ASSERT(memcmp(status, &expected, sizeof(expected)) == 0);
   census_tag tag;
   GPR_ASSERT(census_context_get_tag(
@@ -262,7 +273,7 @@
   const census_context_status *status;
   struct census_context *context2 = census_context_create(
       context, modify_tags + DELETE_TAG_OFFSET, 1, &status);
-  census_context_status expected = {2, 1, 4, 1, 0, 0, 0, 0};
+  census_context_status expected = {3, 4, 1, 0, 0, 0, 0};
   GPR_ASSERT(memcmp(status, &expected, sizeof(expected)) == 0);
   census_tag tag;
   GPR_ASSERT(census_context_get_tag(
@@ -278,7 +289,7 @@
   const census_context_status *status;
   struct census_context *context2 =
       census_context_create(context, modify_tags + ADD_TAG_OFFSET, 1, &status);
-  census_context_status expected = {2, 2, 5, 0, 1, 0, 0, 0};
+  census_context_status expected = {4, 5, 0, 1, 0, 0, 0};
   GPR_ASSERT(memcmp(status, &expected, sizeof(expected)) == 0);
   census_tag tag;
   GPR_ASSERT(census_context_get_tag(context2, modify_tags[ADD_TAG_OFFSET].key,
@@ -295,24 +306,24 @@
   const census_context_status *status;
   struct census_context *context2 =
       census_context_create(context, modify_tags, MODIFY_TAG_COUNT, &status);
-  census_context_status expected = {2, 1, 6, 2, 3, 4, 0, 2};
+  census_context_status expected = {3, 7, 1, 3, 4, 0, 0};
   GPR_ASSERT(memcmp(status, &expected, sizeof(expected)) == 0);
   // validate context contents. Use specific indices into the two arrays
   // holding tag values.
   GPR_ASSERT(validate_tag(context2, &basic_tags[3]));
   GPR_ASSERT(validate_tag(context2, &basic_tags[4]));
+  GPR_ASSERT(validate_tag(context2, &basic_tags[6]));
   GPR_ASSERT(validate_tag(context2, &modify_tags[0]));
   GPR_ASSERT(validate_tag(context2, &modify_tags[1]));
+  GPR_ASSERT(validate_tag(context2, &modify_tags[5]));
   GPR_ASSERT(validate_tag(context2, &modify_tags[6]));
   GPR_ASSERT(validate_tag(context2, &modify_tags[7]));
   GPR_ASSERT(validate_tag(context2, &modify_tags[8]));
   GPR_ASSERT(validate_tag(context2, &modify_tags[9]));
-  GPR_ASSERT(validate_tag(context2, &modify_tags[10]));
   GPR_ASSERT(!validate_tag(context2, &basic_tags[0]));
   GPR_ASSERT(!validate_tag(context2, &basic_tags[1]));
   GPR_ASSERT(!validate_tag(context2, &basic_tags[2]));
   GPR_ASSERT(!validate_tag(context2, &basic_tags[5]));
-  GPR_ASSERT(!validate_tag(context2, &basic_tags[6]));
   GPR_ASSERT(!validate_tag(context2, &basic_tags[7]));
   census_context_destroy(context);
   census_context_destroy(context2);
@@ -325,21 +336,15 @@
   char buffer[BUF_SIZE];
   struct census_context *context =
       census_context_create(NULL, basic_tags, BASIC_TAG_COUNT, NULL);
-  size_t print_bsize;
-  size_t bin_bsize;
   // Test with too small a buffer
-  GPR_ASSERT(census_context_encode(context, buffer, 2, &print_bsize,
-                                   &bin_bsize) == NULL);
-  char *b_buffer = census_context_encode(context, buffer, BUF_SIZE,
-                                         &print_bsize, &bin_bsize);
-  GPR_ASSERT(b_buffer != NULL && print_bsize > 0 && bin_bsize > 0 &&
-             print_bsize + bin_bsize <= BUF_SIZE &&
-             b_buffer == buffer + print_bsize);
-  census_context *context2 =
-      census_context_decode(buffer, print_bsize, b_buffer, bin_bsize);
+  GPR_ASSERT(census_context_encode(context, buffer, 2) == 0);
+  // Test with sufficient buffer
+  size_t buf_used = census_context_encode(context, buffer, BUF_SIZE);
+  GPR_ASSERT(buf_used != 0);
+  census_context *context2 = census_context_decode(buffer, buf_used);
   GPR_ASSERT(context2 != NULL);
   const census_context_status *status = census_context_get_status(context2);
-  census_context_status expected = {2, 2, 0, 0, 0, 0, 0, 0};
+  census_context_status expected = {4, 0, 0, 0, 0, 0, 0};
   GPR_ASSERT(memcmp(status, &expected, sizeof(expected)) == 0);
   for (int i = 0; i < BASIC_TAG_COUNT; i++) {
     census_tag tag;
diff --git a/test/core/census/log_test.c b/test/core/census/mlog_test.c
similarity index 99%
rename from test/core/census/log_test.c
rename to test/core/census/mlog_test.c
index b68ca11..5b6c594 100644
--- a/test/core/census/log_test.c
+++ b/test/core/census/mlog_test.c
@@ -31,7 +31,7 @@
  *
  */
 
-#include "src/core/census/log.h"
+#include "src/core/census/mlog.h"
 #include <grpc/support/cpu.h>
 #include <grpc/support/log.h>
 #include <grpc/support/port_platform.h>
diff --git a/test/core/client_config/set_initial_connect_string_test.c b/test/core/client_config/set_initial_connect_string_test.c
index bcd1f26..3cf267f 100644
--- a/test/core/client_config/set_initial_connect_string_test.c
+++ b/test/core/client_config/set_initial_connect_string_test.c
@@ -85,7 +85,7 @@
   gpr_slice_buffer_init(&state.incoming_buffer);
   gpr_slice_buffer_init(&state.temp_incoming_buffer);
   state.tcp = tcp;
-  grpc_endpoint_add_to_pollset(exec_ctx, tcp, &server->pollset);
+  grpc_endpoint_add_to_pollset(exec_ctx, tcp, server->pollset);
   grpc_endpoint_read(exec_ctx, tcp, &state.temp_incoming_buffer, &on_read);
 }
 
diff --git a/test/core/end2end/end2end_nosec_tests.c b/test/core/end2end/end2end_nosec_tests.c
index 9ff46d6..17dc190 100644
--- a/test/core/end2end/end2end_nosec_tests.c
+++ b/test/core/end2end/end2end_nosec_tests.c
@@ -46,9 +46,8 @@
 extern void cancel_before_invoke(grpc_end2end_test_config config);
 extern void cancel_in_a_vacuum(grpc_end2end_test_config config);
 extern void cancel_with_status(grpc_end2end_test_config config);
-extern void channel_connectivity(grpc_end2end_test_config config);
-extern void channel_ping(grpc_end2end_test_config config);
 extern void compressed_payload(grpc_end2end_test_config config);
+extern void connectivity(grpc_end2end_test_config config);
 extern void default_host(grpc_end2end_test_config config);
 extern void disappearing_server(grpc_end2end_test_config config);
 extern void empty_batch(grpc_end2end_test_config config);
@@ -59,10 +58,10 @@
 extern void large_metadata(grpc_end2end_test_config config);
 extern void max_concurrent_streams(grpc_end2end_test_config config);
 extern void max_message_length(grpc_end2end_test_config config);
-extern void metadata(grpc_end2end_test_config config);
 extern void negative_deadline(grpc_end2end_test_config config);
 extern void no_op(grpc_end2end_test_config config);
 extern void payload(grpc_end2end_test_config config);
+extern void ping(grpc_end2end_test_config config);
 extern void ping_pong_streaming(grpc_end2end_test_config config);
 extern void registered_call(grpc_end2end_test_config config);
 extern void request_with_flags(grpc_end2end_test_config config);
@@ -71,6 +70,7 @@
 extern void shutdown_finishes_calls(grpc_end2end_test_config config);
 extern void shutdown_finishes_tags(grpc_end2end_test_config config);
 extern void simple_delayed_request(grpc_end2end_test_config config);
+extern void simple_metadata(grpc_end2end_test_config config);
 extern void simple_request(grpc_end2end_test_config config);
 extern void trailing_metadata(grpc_end2end_test_config config);
 
@@ -87,9 +87,8 @@
     cancel_before_invoke(config);
     cancel_in_a_vacuum(config);
     cancel_with_status(config);
-    channel_connectivity(config);
-    channel_ping(config);
     compressed_payload(config);
+    connectivity(config);
     default_host(config);
     disappearing_server(config);
     empty_batch(config);
@@ -100,10 +99,10 @@
     large_metadata(config);
     max_concurrent_streams(config);
     max_message_length(config);
-    metadata(config);
     negative_deadline(config);
     no_op(config);
     payload(config);
+    ping(config);
     ping_pong_streaming(config);
     registered_call(config);
     request_with_flags(config);
@@ -112,6 +111,7 @@
     shutdown_finishes_calls(config);
     shutdown_finishes_tags(config);
     simple_delayed_request(config);
+    simple_metadata(config);
     simple_request(config);
     trailing_metadata(config);
     return;
@@ -150,18 +150,14 @@
       cancel_with_status(config);
       continue;
     }
-    if (0 == strcmp("channel_connectivity", argv[i])) {
-      channel_connectivity(config);
-      continue;
-    }
-    if (0 == strcmp("channel_ping", argv[i])) {
-      channel_ping(config);
-      continue;
-    }
     if (0 == strcmp("compressed_payload", argv[i])) {
       compressed_payload(config);
       continue;
     }
+    if (0 == strcmp("connectivity", argv[i])) {
+      connectivity(config);
+      continue;
+    }
     if (0 == strcmp("default_host", argv[i])) {
       default_host(config);
       continue;
@@ -202,10 +198,6 @@
       max_message_length(config);
       continue;
     }
-    if (0 == strcmp("metadata", argv[i])) {
-      metadata(config);
-      continue;
-    }
     if (0 == strcmp("negative_deadline", argv[i])) {
       negative_deadline(config);
       continue;
@@ -218,6 +210,10 @@
       payload(config);
       continue;
     }
+    if (0 == strcmp("ping", argv[i])) {
+      ping(config);
+      continue;
+    }
     if (0 == strcmp("ping_pong_streaming", argv[i])) {
       ping_pong_streaming(config);
       continue;
@@ -250,6 +246,10 @@
       simple_delayed_request(config);
       continue;
     }
+    if (0 == strcmp("simple_metadata", argv[i])) {
+      simple_metadata(config);
+      continue;
+    }
     if (0 == strcmp("simple_request", argv[i])) {
       simple_request(config);
       continue;
diff --git a/test/core/end2end/end2end_tests.c b/test/core/end2end/end2end_tests.c
index 397ff44..6f2f5af 100644
--- a/test/core/end2end/end2end_tests.c
+++ b/test/core/end2end/end2end_tests.c
@@ -47,9 +47,8 @@
 extern void cancel_before_invoke(grpc_end2end_test_config config);
 extern void cancel_in_a_vacuum(grpc_end2end_test_config config);
 extern void cancel_with_status(grpc_end2end_test_config config);
-extern void channel_connectivity(grpc_end2end_test_config config);
-extern void channel_ping(grpc_end2end_test_config config);
 extern void compressed_payload(grpc_end2end_test_config config);
+extern void connectivity(grpc_end2end_test_config config);
 extern void default_host(grpc_end2end_test_config config);
 extern void disappearing_server(grpc_end2end_test_config config);
 extern void empty_batch(grpc_end2end_test_config config);
@@ -60,10 +59,10 @@
 extern void large_metadata(grpc_end2end_test_config config);
 extern void max_concurrent_streams(grpc_end2end_test_config config);
 extern void max_message_length(grpc_end2end_test_config config);
-extern void metadata(grpc_end2end_test_config config);
 extern void negative_deadline(grpc_end2end_test_config config);
 extern void no_op(grpc_end2end_test_config config);
 extern void payload(grpc_end2end_test_config config);
+extern void ping(grpc_end2end_test_config config);
 extern void ping_pong_streaming(grpc_end2end_test_config config);
 extern void registered_call(grpc_end2end_test_config config);
 extern void request_with_flags(grpc_end2end_test_config config);
@@ -72,6 +71,7 @@
 extern void shutdown_finishes_calls(grpc_end2end_test_config config);
 extern void shutdown_finishes_tags(grpc_end2end_test_config config);
 extern void simple_delayed_request(grpc_end2end_test_config config);
+extern void simple_metadata(grpc_end2end_test_config config);
 extern void simple_request(grpc_end2end_test_config config);
 extern void trailing_metadata(grpc_end2end_test_config config);
 
@@ -89,9 +89,8 @@
     cancel_before_invoke(config);
     cancel_in_a_vacuum(config);
     cancel_with_status(config);
-    channel_connectivity(config);
-    channel_ping(config);
     compressed_payload(config);
+    connectivity(config);
     default_host(config);
     disappearing_server(config);
     empty_batch(config);
@@ -102,10 +101,10 @@
     large_metadata(config);
     max_concurrent_streams(config);
     max_message_length(config);
-    metadata(config);
     negative_deadline(config);
     no_op(config);
     payload(config);
+    ping(config);
     ping_pong_streaming(config);
     registered_call(config);
     request_with_flags(config);
@@ -114,6 +113,7 @@
     shutdown_finishes_calls(config);
     shutdown_finishes_tags(config);
     simple_delayed_request(config);
+    simple_metadata(config);
     simple_request(config);
     trailing_metadata(config);
     return;
@@ -156,18 +156,14 @@
       cancel_with_status(config);
       continue;
     }
-    if (0 == strcmp("channel_connectivity", argv[i])) {
-      channel_connectivity(config);
-      continue;
-    }
-    if (0 == strcmp("channel_ping", argv[i])) {
-      channel_ping(config);
-      continue;
-    }
     if (0 == strcmp("compressed_payload", argv[i])) {
       compressed_payload(config);
       continue;
     }
+    if (0 == strcmp("connectivity", argv[i])) {
+      connectivity(config);
+      continue;
+    }
     if (0 == strcmp("default_host", argv[i])) {
       default_host(config);
       continue;
@@ -208,10 +204,6 @@
       max_message_length(config);
       continue;
     }
-    if (0 == strcmp("metadata", argv[i])) {
-      metadata(config);
-      continue;
-    }
     if (0 == strcmp("negative_deadline", argv[i])) {
       negative_deadline(config);
       continue;
@@ -224,6 +216,10 @@
       payload(config);
       continue;
     }
+    if (0 == strcmp("ping", argv[i])) {
+      ping(config);
+      continue;
+    }
     if (0 == strcmp("ping_pong_streaming", argv[i])) {
       ping_pong_streaming(config);
       continue;
@@ -256,6 +252,10 @@
       simple_delayed_request(config);
       continue;
     }
+    if (0 == strcmp("simple_metadata", argv[i])) {
+      simple_metadata(config);
+      continue;
+    }
     if (0 == strcmp("simple_request", argv[i])) {
       simple_request(config);
       continue;
diff --git a/test/core/end2end/fixtures/h2_full+poll+pipe.c b/test/core/end2end/fixtures/h2_full+poll+pipe.c
index d475a7b..682598f 100644
--- a/test/core/end2end/fixtures/h2_full+poll+pipe.c
+++ b/test/core/end2end/fixtures/h2_full+poll+pipe.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -35,21 +35,23 @@
 
 #include <string.h>
 
-#include "src/core/channel/client_channel.h"
-#include "src/core/channel/connected_channel.h"
-#include "src/core/channel/http_server_filter.h"
-#include "src/core/surface/channel.h"
-#include "src/core/surface/server.h"
-#include "src/core/transport/chttp2_transport.h"
 #include <grpc/support/alloc.h>
 #include <grpc/support/host_port.h>
 #include <grpc/support/log.h>
 #include <grpc/support/sync.h>
 #include <grpc/support/thd.h>
 #include <grpc/support/useful.h>
+
+#include "src/core/channel/client_channel.h"
+#include "src/core/channel/connected_channel.h"
+#include "src/core/channel/http_server_filter.h"
+#include "src/core/iomgr/pollset_posix.h"
+#include "src/core/iomgr/wakeup_fd_posix.h"
+#include "src/core/surface/channel.h"
+#include "src/core/surface/server.h"
+#include "src/core/transport/chttp2_transport.h"
 #include "test/core/util/port.h"
 #include "test/core/util/test_config.h"
-#include "src/core/iomgr/wakeup_fd_posix.h"
 
 typedef struct fullstack_fixture_data {
   char *localaddr;
diff --git a/test/core/end2end/fixtures/h2_full+poll.c b/test/core/end2end/fixtures/h2_full+poll.c
index 3f5e609..5a0b2ef 100644
--- a/test/core/end2end/fixtures/h2_full+poll.c
+++ b/test/core/end2end/fixtures/h2_full+poll.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -35,18 +35,20 @@
 
 #include <string.h>
 
-#include "src/core/channel/client_channel.h"
-#include "src/core/channel/connected_channel.h"
-#include "src/core/channel/http_server_filter.h"
-#include "src/core/surface/channel.h"
-#include "src/core/surface/server.h"
-#include "src/core/transport/chttp2_transport.h"
 #include <grpc/support/alloc.h>
 #include <grpc/support/host_port.h>
 #include <grpc/support/log.h>
 #include <grpc/support/sync.h>
 #include <grpc/support/thd.h>
 #include <grpc/support/useful.h>
+
+#include "src/core/channel/client_channel.h"
+#include "src/core/channel/connected_channel.h"
+#include "src/core/channel/http_server_filter.h"
+#include "src/core/iomgr/pollset_posix.h"
+#include "src/core/surface/channel.h"
+#include "src/core/surface/server.h"
+#include "src/core/transport/chttp2_transport.h"
 #include "test/core/util/port.h"
 #include "test/core/util/test_config.h"
 
diff --git a/test/core/end2end/fixtures/h2_ssl+poll.c b/test/core/end2end/fixtures/h2_ssl+poll.c
index 614654e..66268c7 100644
--- a/test/core/end2end/fixtures/h2_ssl+poll.c
+++ b/test/core/end2end/fixtures/h2_ssl+poll.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -36,17 +36,19 @@
 #include <stdio.h>
 #include <string.h>
 
-#include "src/core/channel/channel_args.h"
-#include "src/core/security/credentials.h"
-#include "src/core/support/env.h"
-#include "src/core/support/file.h"
-#include "src/core/support/string.h"
 #include <grpc/support/alloc.h>
 #include <grpc/support/host_port.h>
 #include <grpc/support/log.h>
-#include "test/core/util/test_config.h"
-#include "test/core/util/port.h"
+
+#include "src/core/channel/channel_args.h"
+#include "src/core/iomgr/pollset_posix.h"
+#include "src/core/security/credentials.h"
+#include "src/core/support/env.h"
+#include "src/core/support/tmpfile.h"
+#include "src/core/support/string.h"
 #include "test/core/end2end/data/ssl_test_data.h"
+#include "test/core/util/port.h"
+#include "test/core/util/test_config.h"
 
 typedef struct fullstack_secure_fixture_data {
   char *localaddr;
diff --git a/test/core/end2end/fixtures/h2_ssl.c b/test/core/end2end/fixtures/h2_ssl.c
index 5c63dfb..e21a347 100644
--- a/test/core/end2end/fixtures/h2_ssl.c
+++ b/test/core/end2end/fixtures/h2_ssl.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -36,17 +36,18 @@
 #include <stdio.h>
 #include <string.h>
 
-#include "src/core/channel/channel_args.h"
-#include "src/core/security/credentials.h"
-#include "src/core/support/env.h"
-#include "src/core/support/file.h"
-#include "src/core/support/string.h"
 #include <grpc/support/alloc.h>
 #include <grpc/support/host_port.h>
 #include <grpc/support/log.h>
-#include "test/core/util/test_config.h"
-#include "test/core/util/port.h"
+
+#include "src/core/channel/channel_args.h"
+#include "src/core/security/credentials.h"
+#include "src/core/support/env.h"
+#include "src/core/support/tmpfile.h"
+#include "src/core/support/string.h"
 #include "test/core/end2end/data/ssl_test_data.h"
+#include "test/core/util/port.h"
+#include "test/core/util/test_config.h"
 
 typedef struct fullstack_secure_fixture_data {
   char *localaddr;
diff --git a/test/core/end2end/fixtures/h2_ssl_proxy.c b/test/core/end2end/fixtures/h2_ssl_proxy.c
index a93bd83..6340d3f 100644
--- a/test/core/end2end/fixtures/h2_ssl_proxy.c
+++ b/test/core/end2end/fixtures/h2_ssl_proxy.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -36,18 +36,19 @@
 #include <stdio.h>
 #include <string.h>
 
-#include "src/core/channel/channel_args.h"
-#include "src/core/security/credentials.h"
-#include "src/core/support/env.h"
-#include "src/core/support/file.h"
-#include "src/core/support/string.h"
 #include <grpc/support/alloc.h>
 #include <grpc/support/host_port.h>
 #include <grpc/support/log.h>
+
+#include "src/core/channel/channel_args.h"
+#include "src/core/security/credentials.h"
+#include "src/core/support/env.h"
+#include "src/core/support/tmpfile.h"
+#include "src/core/support/string.h"
 #include "test/core/end2end/data/ssl_test_data.h"
 #include "test/core/end2end/fixtures/proxy.h"
-#include "test/core/util/test_config.h"
 #include "test/core/util/port.h"
+#include "test/core/util/test_config.h"
 
 typedef struct fullstack_secure_fixture_data {
   grpc_end2end_proxy *proxy;
diff --git a/test/core/end2end/fixtures/h2_uchannel.c b/test/core/end2end/fixtures/h2_uchannel.c
index dbdd352..87bbd64 100644
--- a/test/core/end2end/fixtures/h2_uchannel.c
+++ b/test/core/end2end/fixtures/h2_uchannel.c
@@ -35,6 +35,13 @@
 
 #include <string.h>
 
+#include <grpc/support/alloc.h>
+#include <grpc/support/host_port.h>
+#include <grpc/support/log.h>
+#include <grpc/support/string_util.h>
+#include <grpc/support/sync.h>
+#include <grpc/support/thd.h>
+#include <grpc/support/useful.h>
 #include "src/core/channel/channel_args.h"
 #include "src/core/channel/client_channel.h"
 #include "src/core/channel/client_uchannel.h"
@@ -46,13 +53,6 @@
 #include "src/core/surface/channel.h"
 #include "src/core/surface/server.h"
 #include "src/core/transport/chttp2_transport.h"
-#include <grpc/support/alloc.h>
-#include <grpc/support/host_port.h>
-#include <grpc/support/log.h>
-#include <grpc/support/string_util.h>
-#include <grpc/support/sync.h>
-#include <grpc/support/thd.h>
-#include <grpc/support/useful.h>
 #include "test/core/util/port.h"
 #include "test/core/util/test_config.h"
 
@@ -238,12 +238,12 @@
 }
 
 grpc_connectivity_state g_state = GRPC_CHANNEL_IDLE;
-grpc_pollset_set g_interested_parties;
+grpc_pollset_set *g_interested_parties;
 
 static void state_changed(grpc_exec_ctx *exec_ctx, void *arg, bool success) {
   if (g_state != GRPC_CHANNEL_READY) {
     grpc_subchannel_notify_on_state_change(
-        exec_ctx, arg, &g_interested_parties, &g_state,
+        exec_ctx, arg, g_interested_parties, &g_state,
         grpc_closure_create(state_changed, arg));
   }
 }
@@ -253,30 +253,31 @@
 }
 
 static grpc_connected_subchannel *connect_subchannel(grpc_subchannel *c) {
-  grpc_pollset pollset;
+  gpr_mu *mu;
+  grpc_pollset *pollset = gpr_malloc(grpc_pollset_size());
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
-  grpc_pollset_init(&pollset);
-  grpc_pollset_set_init(&g_interested_parties);
-  grpc_pollset_set_add_pollset(&exec_ctx, &g_interested_parties, &pollset);
-  grpc_subchannel_notify_on_state_change(&exec_ctx, c, &g_interested_parties,
+  grpc_pollset_init(pollset, &mu);
+  g_interested_parties = grpc_pollset_set_create();
+  grpc_pollset_set_add_pollset(&exec_ctx, g_interested_parties, pollset);
+  grpc_subchannel_notify_on_state_change(&exec_ctx, c, g_interested_parties,
                                          &g_state,
                                          grpc_closure_create(state_changed, c));
   grpc_exec_ctx_flush(&exec_ctx);
-  gpr_mu_lock(GRPC_POLLSET_MU(&pollset));
+  gpr_mu_lock(mu);
   while (g_state != GRPC_CHANNEL_READY) {
-    grpc_pollset_worker worker;
-    grpc_pollset_work(&exec_ctx, &pollset, &worker,
-                      gpr_now(GPR_CLOCK_MONOTONIC),
+    grpc_pollset_worker *worker = NULL;
+    grpc_pollset_work(&exec_ctx, pollset, &worker, gpr_now(GPR_CLOCK_MONOTONIC),
                       GRPC_TIMEOUT_SECONDS_TO_DEADLINE(1));
-    gpr_mu_unlock(GRPC_POLLSET_MU(&pollset));
+    gpr_mu_unlock(mu);
     grpc_exec_ctx_flush(&exec_ctx);
-    gpr_mu_lock(GRPC_POLLSET_MU(&pollset));
+    gpr_mu_lock(mu);
   }
-  grpc_pollset_shutdown(&exec_ctx, &pollset,
-                        grpc_closure_create(destroy_pollset, &pollset));
-  grpc_pollset_set_destroy(&g_interested_parties);
-  gpr_mu_unlock(GRPC_POLLSET_MU(&pollset));
+  grpc_pollset_shutdown(&exec_ctx, pollset,
+                        grpc_closure_create(destroy_pollset, pollset));
+  grpc_pollset_set_destroy(g_interested_parties);
+  gpr_mu_unlock(mu);
   grpc_exec_ctx_finish(&exec_ctx);
+  gpr_free(pollset);
   return grpc_subchannel_get_connected_subchannel(c);
 }
 
diff --git a/test/core/end2end/fixtures/h2_uds+poll.c b/test/core/end2end/fixtures/h2_uds+poll.c
index 155017c..c3a855f 100644
--- a/test/core/end2end/fixtures/h2_uds+poll.c
+++ b/test/core/end2end/fixtures/h2_uds+poll.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -37,13 +37,6 @@
 #include <string.h>
 #include <unistd.h>
 
-#include "src/core/channel/client_channel.h"
-#include "src/core/channel/connected_channel.h"
-#include "src/core/channel/http_server_filter.h"
-#include "src/core/support/string.h"
-#include "src/core/surface/channel.h"
-#include "src/core/surface/server.h"
-#include "src/core/transport/chttp2_transport.h"
 #include <grpc/support/alloc.h>
 #include <grpc/support/host_port.h>
 #include <grpc/support/log.h>
@@ -51,6 +44,15 @@
 #include <grpc/support/sync.h>
 #include <grpc/support/thd.h>
 #include <grpc/support/useful.h>
+
+#include "src/core/channel/client_channel.h"
+#include "src/core/channel/connected_channel.h"
+#include "src/core/channel/http_server_filter.h"
+#include "src/core/iomgr/pollset_posix.h"
+#include "src/core/support/string.h"
+#include "src/core/surface/channel.h"
+#include "src/core/surface/server.h"
+#include "src/core/transport/chttp2_transport.h"
 #include "test/core/util/port.h"
 #include "test/core/util/test_config.h"
 
diff --git a/test/core/end2end/gen_build_yaml.py b/test/core/end2end/gen_build_yaml.py
index f24dbe7..4dfafce 100755
--- a/test/core/end2end/gen_build_yaml.py
+++ b/test/core/end2end/gen_build_yaml.py
@@ -94,9 +94,8 @@
     'cancel_before_invoke': default_test_options._replace(cpu_cost=LOWCPU),
     'cancel_in_a_vacuum': default_test_options._replace(cpu_cost=LOWCPU),
     'cancel_with_status': default_test_options._replace(cpu_cost=LOWCPU),
-    'channel_connectivity': connectivity_test_options._replace(proxyable=False, cpu_cost=LOWCPU),
-    'channel_ping': connectivity_test_options._replace(proxyable=False),
     'compressed_payload': default_test_options._replace(proxyable=False, cpu_cost=LOWCPU),
+    'connectivity': connectivity_test_options._replace(proxyable=False, cpu_cost=LOWCPU),
     'default_host': default_test_options._replace(needs_fullstack=True,
                                                   needs_dns=True),
     'disappearing_server': connectivity_test_options,
@@ -109,11 +108,11 @@
     'large_metadata': default_test_options,
     'max_concurrent_streams': default_test_options._replace(proxyable=False),
     'max_message_length': default_test_options._replace(cpu_cost=LOWCPU),
-    'metadata': default_test_options,
     'negative_deadline': default_test_options,
     'no_op': default_test_options,
     'payload': default_test_options._replace(cpu_cost=LOWCPU),
     'ping_pong_streaming': default_test_options,
+    'ping': connectivity_test_options._replace(proxyable=False),
     'registered_call': default_test_options,
     'request_with_flags': default_test_options._replace(proxyable=False),
     'request_with_payload': default_test_options,
@@ -121,6 +120,7 @@
     'shutdown_finishes_calls': default_test_options,
     'shutdown_finishes_tags': default_test_options,
     'simple_delayed_request': connectivity_test_options._replace(cpu_cost=LOWCPU),
+    'simple_metadata': default_test_options,
     'simple_request': default_test_options,
     'trailing_metadata': default_test_options,
 }
diff --git a/test/core/end2end/tests/channel_connectivity.c b/test/core/end2end/tests/connectivity.c
similarity index 98%
rename from test/core/end2end/tests/channel_connectivity.c
rename to test/core/end2end/tests/connectivity.c
index 0e21e65..975c620 100644
--- a/test/core/end2end/tests/channel_connectivity.c
+++ b/test/core/end2end/tests/connectivity.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -168,7 +168,7 @@
   cq_verifier_destroy(cqv);
 }
 
-void channel_connectivity(grpc_end2end_test_config config) {
+void connectivity(grpc_end2end_test_config config) {
   GPR_ASSERT(config.feature_mask & FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION);
   test_connectivity(config);
 }
diff --git a/test/core/end2end/tests/channel_ping.c b/test/core/end2end/tests/ping.c
similarity index 97%
rename from test/core/end2end/tests/channel_ping.c
rename to test/core/end2end/tests/ping.c
index 73fab20..f85df63 100644
--- a/test/core/end2end/tests/channel_ping.c
+++ b/test/core/end2end/tests/ping.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -91,7 +91,7 @@
   cq_verifier_destroy(cqv);
 }
 
-void channel_ping(grpc_end2end_test_config config) {
+void ping(grpc_end2end_test_config config) {
   GPR_ASSERT(config.feature_mask & FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION);
   test_ping(config);
 }
diff --git a/test/core/end2end/tests/metadata.c b/test/core/end2end/tests/simple_metadata.c
similarity index 98%
rename from test/core/end2end/tests/metadata.c
rename to test/core/end2end/tests/simple_metadata.c
index 5e92091..c5084a5 100644
--- a/test/core/end2end/tests/metadata.c
+++ b/test/core/end2end/tests/simple_metadata.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -260,6 +260,6 @@
   config.tear_down_data(&f);
 }
 
-void metadata(grpc_end2end_test_config config) {
+void simple_metadata(grpc_end2end_test_config config) {
   test_request_response_with_metadata_and_payload(config);
 }
diff --git a/test/core/httpcli/httpcli_test.c b/test/core/httpcli/httpcli_test.c
index 651ef1f..da14633 100644
--- a/test/core/httpcli/httpcli_test.c
+++ b/test/core/httpcli/httpcli_test.c
@@ -36,18 +36,19 @@
 #include <string.h>
 
 #include <grpc/grpc.h>
-#include "src/core/iomgr/iomgr.h"
 #include <grpc/support/alloc.h>
 #include <grpc/support/log.h>
 #include <grpc/support/string_util.h>
 #include <grpc/support/subprocess.h>
 #include <grpc/support/sync.h>
+#include "src/core/iomgr/iomgr.h"
 #include "test/core/util/port.h"
 #include "test/core/util/test_config.h"
 
 static int g_done = 0;
 static grpc_httpcli_context g_context;
-static grpc_pollset g_pollset;
+static gpr_mu *g_mu;
+static grpc_pollset *g_pollset;
 
 static gpr_timespec n_seconds_time(int seconds) {
   return GRPC_TIMEOUT_SECONDS_TO_DEADLINE(seconds);
@@ -63,10 +64,10 @@
   GPR_ASSERT(response->status == 200);
   GPR_ASSERT(response->body_length == strlen(expect));
   GPR_ASSERT(0 == memcmp(expect, response->body, response->body_length));
-  gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
+  gpr_mu_lock(g_mu);
   g_done = 1;
-  grpc_pollset_kick(&g_pollset, NULL);
-  gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
+  grpc_pollset_kick(g_pollset, NULL);
+  gpr_mu_unlock(g_mu);
 }
 
 static void test_get(int port) {
@@ -85,18 +86,18 @@
   req.path = "/get";
   req.handshaker = &grpc_httpcli_plaintext;
 
-  grpc_httpcli_get(&exec_ctx, &g_context, &g_pollset, &req, n_seconds_time(15),
+  grpc_httpcli_get(&exec_ctx, &g_context, g_pollset, &req, n_seconds_time(15),
                    on_finish, (void *)42);
-  gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
+  gpr_mu_lock(g_mu);
   while (!g_done) {
-    grpc_pollset_worker worker;
-    grpc_pollset_work(&exec_ctx, &g_pollset, &worker,
+    grpc_pollset_worker *worker = NULL;
+    grpc_pollset_work(&exec_ctx, g_pollset, &worker,
                       gpr_now(GPR_CLOCK_MONOTONIC), n_seconds_time(20));
-    gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
+    gpr_mu_unlock(g_mu);
     grpc_exec_ctx_finish(&exec_ctx);
-    gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
+    gpr_mu_lock(g_mu);
   }
-  gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
+  gpr_mu_unlock(g_mu);
   gpr_free(host);
 }
 
@@ -116,18 +117,18 @@
   req.path = "/post";
   req.handshaker = &grpc_httpcli_plaintext;
 
-  grpc_httpcli_post(&exec_ctx, &g_context, &g_pollset, &req, "hello", 5,
+  grpc_httpcli_post(&exec_ctx, &g_context, g_pollset, &req, "hello", 5,
                     n_seconds_time(15), on_finish, (void *)42);
-  gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
+  gpr_mu_lock(g_mu);
   while (!g_done) {
-    grpc_pollset_worker worker;
-    grpc_pollset_work(&exec_ctx, &g_pollset, &worker,
+    grpc_pollset_worker *worker = NULL;
+    grpc_pollset_work(&exec_ctx, g_pollset, &worker,
                       gpr_now(GPR_CLOCK_MONOTONIC), n_seconds_time(20));
-    gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
+    gpr_mu_unlock(g_mu);
     grpc_exec_ctx_finish(&exec_ctx);
-    gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
+    gpr_mu_lock(g_mu);
   }
-  gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
+  gpr_mu_unlock(g_mu);
   gpr_free(host);
 }
 
@@ -175,17 +176,20 @@
   grpc_test_init(argc, argv);
   grpc_init();
   grpc_httpcli_context_init(&g_context);
-  grpc_pollset_init(&g_pollset);
+  g_pollset = gpr_malloc(grpc_pollset_size());
+  grpc_pollset_init(g_pollset, &g_mu);
 
   test_get(port);
   test_post(port);
 
   grpc_httpcli_context_destroy(&g_context);
-  grpc_closure_init(&destroyed, destroy_pollset, &g_pollset);
-  grpc_pollset_shutdown(&exec_ctx, &g_pollset, &destroyed);
+  grpc_closure_init(&destroyed, destroy_pollset, g_pollset);
+  grpc_pollset_shutdown(&exec_ctx, g_pollset, &destroyed);
   grpc_exec_ctx_finish(&exec_ctx);
   grpc_shutdown();
 
+  gpr_free(g_pollset);
+
   gpr_subprocess_destroy(server);
 
   return 0;
diff --git a/test/core/httpcli/httpscli_test.c b/test/core/httpcli/httpscli_test.c
index db41be1..7f765bc 100644
--- a/test/core/httpcli/httpscli_test.c
+++ b/test/core/httpcli/httpscli_test.c
@@ -36,18 +36,19 @@
 #include <string.h>
 
 #include <grpc/grpc.h>
-#include "src/core/iomgr/iomgr.h"
 #include <grpc/support/alloc.h>
 #include <grpc/support/log.h>
 #include <grpc/support/string_util.h>
 #include <grpc/support/subprocess.h>
 #include <grpc/support/sync.h>
+#include "src/core/iomgr/iomgr.h"
 #include "test/core/util/port.h"
 #include "test/core/util/test_config.h"
 
 static int g_done = 0;
 static grpc_httpcli_context g_context;
-static grpc_pollset g_pollset;
+static gpr_mu *g_mu;
+static grpc_pollset *g_pollset;
 
 static gpr_timespec n_seconds_time(int seconds) {
   return GRPC_TIMEOUT_SECONDS_TO_DEADLINE(seconds);
@@ -63,10 +64,10 @@
   GPR_ASSERT(response->status == 200);
   GPR_ASSERT(response->body_length == strlen(expect));
   GPR_ASSERT(0 == memcmp(expect, response->body, response->body_length));
-  gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
+  gpr_mu_lock(g_mu);
   g_done = 1;
-  grpc_pollset_kick(&g_pollset, NULL);
-  gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
+  grpc_pollset_kick(g_pollset, NULL);
+  gpr_mu_unlock(g_mu);
 }
 
 static void test_get(int port) {
@@ -86,18 +87,18 @@
   req.path = "/get";
   req.handshaker = &grpc_httpcli_ssl;
 
-  grpc_httpcli_get(&exec_ctx, &g_context, &g_pollset, &req, n_seconds_time(15),
+  grpc_httpcli_get(&exec_ctx, &g_context, g_pollset, &req, n_seconds_time(15),
                    on_finish, (void *)42);
-  gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
+  gpr_mu_lock(g_mu);
   while (!g_done) {
-    grpc_pollset_worker worker;
-    grpc_pollset_work(&exec_ctx, &g_pollset, &worker,
+    grpc_pollset_worker *worker = NULL;
+    grpc_pollset_work(&exec_ctx, g_pollset, &worker,
                       gpr_now(GPR_CLOCK_MONOTONIC), n_seconds_time(20));
-    gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
+    gpr_mu_unlock(g_mu);
     grpc_exec_ctx_finish(&exec_ctx);
-    gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
+    gpr_mu_lock(g_mu);
   }
-  gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
+  gpr_mu_unlock(g_mu);
   gpr_free(host);
 }
 
@@ -118,18 +119,18 @@
   req.path = "/post";
   req.handshaker = &grpc_httpcli_ssl;
 
-  grpc_httpcli_post(&exec_ctx, &g_context, &g_pollset, &req, "hello", 5,
+  grpc_httpcli_post(&exec_ctx, &g_context, g_pollset, &req, "hello", 5,
                     n_seconds_time(15), on_finish, (void *)42);
-  gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
+  gpr_mu_lock(g_mu);
   while (!g_done) {
-    grpc_pollset_worker worker;
-    grpc_pollset_work(&exec_ctx, &g_pollset, &worker,
+    grpc_pollset_worker *worker = NULL;
+    grpc_pollset_work(&exec_ctx, g_pollset, &worker,
                       gpr_now(GPR_CLOCK_MONOTONIC), n_seconds_time(20));
-    gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
+    gpr_mu_unlock(g_mu);
     grpc_exec_ctx_finish(&exec_ctx);
-    gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
+    gpr_mu_lock(g_mu);
   }
-  gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
+  gpr_mu_unlock(g_mu);
   gpr_free(host);
 }
 
@@ -178,17 +179,20 @@
   grpc_test_init(argc, argv);
   grpc_init();
   grpc_httpcli_context_init(&g_context);
-  grpc_pollset_init(&g_pollset);
+  g_pollset = gpr_malloc(grpc_pollset_size());
+  grpc_pollset_init(g_pollset, &g_mu);
 
   test_get(port);
   test_post(port);
 
   grpc_httpcli_context_destroy(&g_context);
-  grpc_closure_init(&destroyed, destroy_pollset, &g_pollset);
-  grpc_pollset_shutdown(&exec_ctx, &g_pollset, &destroyed);
+  grpc_closure_init(&destroyed, destroy_pollset, g_pollset);
+  grpc_pollset_shutdown(&exec_ctx, g_pollset, &destroyed);
   grpc_exec_ctx_finish(&exec_ctx);
   grpc_shutdown();
 
+  gpr_free(g_pollset);
+
   gpr_subprocess_destroy(server);
 
   return 0;
diff --git a/test/core/iomgr/endpoint_pair_test.c b/test/core/iomgr/endpoint_pair_test.c
index 7e266eb..c3a9108 100644
--- a/test/core/iomgr/endpoint_pair_test.c
+++ b/test/core/iomgr/endpoint_pair_test.c
@@ -39,10 +39,11 @@
 #include <grpc/support/time.h>
 #include <grpc/support/useful.h>
 #include "src/core/iomgr/endpoint_pair.h"
-#include "test/core/util/test_config.h"
 #include "test/core/iomgr/endpoint_tests.h"
+#include "test/core/util/test_config.h"
 
-static grpc_pollset g_pollset;
+static gpr_mu *g_mu;
+static grpc_pollset *g_pollset;
 
 static void clean_up(void) {}
 
@@ -54,8 +55,8 @@
 
   f.client_ep = p.client;
   f.server_ep = p.server;
-  grpc_endpoint_add_to_pollset(&exec_ctx, f.client_ep, &g_pollset);
-  grpc_endpoint_add_to_pollset(&exec_ctx, f.server_ep, &g_pollset);
+  grpc_endpoint_add_to_pollset(&exec_ctx, f.client_ep, g_pollset);
+  grpc_endpoint_add_to_pollset(&exec_ctx, f.server_ep, g_pollset);
   grpc_exec_ctx_finish(&exec_ctx);
 
   return f;
@@ -74,12 +75,14 @@
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   grpc_test_init(argc, argv);
   grpc_init();
-  grpc_pollset_init(&g_pollset);
-  grpc_endpoint_tests(configs[0], &g_pollset);
-  grpc_closure_init(&destroyed, destroy_pollset, &g_pollset);
-  grpc_pollset_shutdown(&exec_ctx, &g_pollset, &destroyed);
+  g_pollset = gpr_malloc(grpc_pollset_size());
+  grpc_pollset_init(g_pollset, &g_mu);
+  grpc_endpoint_tests(configs[0], g_pollset, g_mu);
+  grpc_closure_init(&destroyed, destroy_pollset, g_pollset);
+  grpc_pollset_shutdown(&exec_ctx, g_pollset, &destroyed);
   grpc_exec_ctx_finish(&exec_ctx);
   grpc_shutdown();
+  gpr_free(g_pollset);
 
   return 0;
 }
diff --git a/test/core/iomgr/endpoint_tests.c b/test/core/iomgr/endpoint_tests.c
index 1b6a78d..f689e4b 100644
--- a/test/core/iomgr/endpoint_tests.c
+++ b/test/core/iomgr/endpoint_tests.c
@@ -36,8 +36,8 @@
 #include <sys/types.h>
 
 #include <grpc/support/alloc.h>
-#include <grpc/support/slice.h>
 #include <grpc/support/log.h>
+#include <grpc/support/slice.h>
 #include <grpc/support/time.h>
 #include <grpc/support/useful.h>
 #include "test/core/util/test_config.h"
@@ -58,6 +58,7 @@
 
 */
 
+static gpr_mu *g_mu;
 static grpc_pollset *g_pollset;
 
 size_t count_slices(gpr_slice *slices, size_t nslices, int *current_data) {
@@ -134,10 +135,10 @@
       state->incoming.slices, state->incoming.count, &state->current_read_data);
   if (state->bytes_read == state->target_bytes || !success) {
     gpr_log(GPR_INFO, "Read handler done");
-    gpr_mu_lock(GRPC_POLLSET_MU(g_pollset));
+    gpr_mu_lock(g_mu);
     state->read_done = 1 + success;
     grpc_pollset_kick(g_pollset, NULL);
-    gpr_mu_unlock(GRPC_POLLSET_MU(g_pollset));
+    gpr_mu_unlock(g_mu);
   } else if (success) {
     grpc_endpoint_read(exec_ctx, state->read_ep, &state->incoming,
                        &state->done_read);
@@ -169,10 +170,10 @@
   }
 
   gpr_log(GPR_INFO, "Write handler done");
-  gpr_mu_lock(GRPC_POLLSET_MU(g_pollset));
+  gpr_mu_lock(g_mu);
   state->write_done = 1 + success;
   grpc_pollset_kick(g_pollset, NULL);
-  gpr_mu_unlock(GRPC_POLLSET_MU(g_pollset));
+  gpr_mu_unlock(g_mu);
 }
 
 /* Do both reading and writing using the grpc_endpoint API.
@@ -232,14 +233,14 @@
   }
   grpc_exec_ctx_finish(&exec_ctx);
 
-  gpr_mu_lock(GRPC_POLLSET_MU(g_pollset));
+  gpr_mu_lock(g_mu);
   while (!state.read_done || !state.write_done) {
-    grpc_pollset_worker worker;
+    grpc_pollset_worker *worker = NULL;
     GPR_ASSERT(gpr_time_cmp(gpr_now(GPR_CLOCK_MONOTONIC), deadline) < 0);
     grpc_pollset_work(&exec_ctx, g_pollset, &worker,
                       gpr_now(GPR_CLOCK_MONOTONIC), deadline);
   }
-  gpr_mu_unlock(GRPC_POLLSET_MU(g_pollset));
+  gpr_mu_unlock(g_mu);
   grpc_exec_ctx_finish(&exec_ctx);
 
   end_test(config);
@@ -251,9 +252,10 @@
 }
 
 void grpc_endpoint_tests(grpc_endpoint_test_config config,
-                         grpc_pollset *pollset) {
+                         grpc_pollset *pollset, gpr_mu *mu) {
   size_t i;
   g_pollset = pollset;
+  g_mu = mu;
   read_and_write_test(config, 10000000, 100000, 8192, 0);
   read_and_write_test(config, 1000000, 100000, 1, 0);
   read_and_write_test(config, 100000000, 100000, 1, 1);
diff --git a/test/core/iomgr/endpoint_tests.h b/test/core/iomgr/endpoint_tests.h
index 700f854..8ea47e3 100644
--- a/test/core/iomgr/endpoint_tests.h
+++ b/test/core/iomgr/endpoint_tests.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -53,6 +53,6 @@
 };
 
 void grpc_endpoint_tests(grpc_endpoint_test_config config,
-                         grpc_pollset *pollset);
+                         grpc_pollset *pollset, gpr_mu *mu);
 
 #endif /* GRPC_TEST_CORE_IOMGR_ENDPOINT_TESTS_H */
diff --git a/test/core/iomgr/fd_posix_test.c b/test/core/iomgr/fd_posix_test.c
index 347a86a..99689eb 100644
--- a/test/core/iomgr/fd_posix_test.c
+++ b/test/core/iomgr/fd_posix_test.c
@@ -49,9 +49,12 @@
 #include <grpc/support/log.h>
 #include <grpc/support/sync.h>
 #include <grpc/support/time.h>
+
+#include "src/core/iomgr/pollset_posix.h"
 #include "test/core/util/test_config.h"
 
-static grpc_pollset g_pollset;
+static gpr_mu *g_mu;
+static grpc_pollset *g_pollset;
 
 /* buffer size used to send and receive data.
    1024 is the minimal value to set TCP send and receive buffer. */
@@ -179,10 +182,10 @@
 
   grpc_fd_orphan(exec_ctx, sv->em_fd, NULL, NULL, "b");
 
-  gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
+  gpr_mu_lock(g_mu);
   sv->done = 1;
-  grpc_pollset_kick(&g_pollset, NULL);
-  gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
+  grpc_pollset_kick(g_pollset, NULL);
+  gpr_mu_unlock(g_mu);
 }
 
 /* Called when a new TCP connection request arrives in the listening port. */
@@ -209,7 +212,7 @@
   se = gpr_malloc(sizeof(*se));
   se->sv = sv;
   se->em_fd = grpc_fd_create(fd, "listener");
-  grpc_pollset_add_fd(exec_ctx, &g_pollset, se->em_fd);
+  grpc_pollset_add_fd(exec_ctx, g_pollset, se->em_fd);
   se->session_read_closure.cb = session_read_cb;
   se->session_read_closure.cb_arg = se;
   grpc_fd_notify_on_read(exec_ctx, se->em_fd, &se->session_read_closure);
@@ -238,7 +241,7 @@
   GPR_ASSERT(listen(fd, MAX_NUM_FD) == 0);
 
   sv->em_fd = grpc_fd_create(fd, "server");
-  grpc_pollset_add_fd(exec_ctx, &g_pollset, sv->em_fd);
+  grpc_pollset_add_fd(exec_ctx, g_pollset, sv->em_fd);
   /* Register to be interested in reading from listen_fd. */
   sv->listen_closure.cb = listen_cb;
   sv->listen_closure.cb_arg = sv;
@@ -249,18 +252,18 @@
 
 /* Wait and shutdown a sever. */
 static void server_wait_and_shutdown(server *sv) {
-  gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
+  gpr_mu_lock(g_mu);
   while (!sv->done) {
     grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
-    grpc_pollset_worker worker;
-    grpc_pollset_work(&exec_ctx, &g_pollset, &worker,
+    grpc_pollset_worker *worker = NULL;
+    grpc_pollset_work(&exec_ctx, g_pollset, &worker,
                       gpr_now(GPR_CLOCK_MONOTONIC),
                       gpr_inf_future(GPR_CLOCK_MONOTONIC));
-    gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
+    gpr_mu_unlock(g_mu);
     grpc_exec_ctx_finish(&exec_ctx);
-    gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
+    gpr_mu_lock(g_mu);
   }
-  gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
+  gpr_mu_unlock(g_mu);
 }
 
 /* ===An upload client to test notify_on_write=== */
@@ -296,7 +299,7 @@
   client *cl = arg;
   grpc_fd_orphan(exec_ctx, cl->em_fd, NULL, NULL, "c");
   cl->done = 1;
-  grpc_pollset_kick(&g_pollset, NULL);
+  grpc_pollset_kick(g_pollset, NULL);
 }
 
 /* Write as much as possible, then register notify_on_write. */
@@ -307,9 +310,9 @@
   ssize_t write_once = 0;
 
   if (!success) {
-    gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
+    gpr_mu_lock(g_mu);
     client_session_shutdown_cb(exec_ctx, arg, 1);
-    gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
+    gpr_mu_unlock(g_mu);
     return;
   }
 
@@ -319,7 +322,7 @@
   } while (write_once > 0);
 
   if (errno == EAGAIN) {
-    gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
+    gpr_mu_lock(g_mu);
     if (cl->client_write_cnt < CLIENT_TOTAL_WRITE_CNT) {
       cl->write_closure.cb = client_session_write;
       cl->write_closure.cb_arg = cl;
@@ -328,7 +331,7 @@
     } else {
       client_session_shutdown_cb(exec_ctx, arg, 1);
     }
-    gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
+    gpr_mu_unlock(g_mu);
   } else {
     gpr_log(GPR_ERROR, "unknown errno %s", strerror(errno));
     abort();
@@ -357,25 +360,25 @@
   }
 
   cl->em_fd = grpc_fd_create(fd, "client");
-  grpc_pollset_add_fd(exec_ctx, &g_pollset, cl->em_fd);
+  grpc_pollset_add_fd(exec_ctx, g_pollset, cl->em_fd);
 
   client_session_write(exec_ctx, cl, 1);
 }
 
 /* Wait for the signal to shutdown a client. */
 static void client_wait_and_shutdown(client *cl) {
-  gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
+  gpr_mu_lock(g_mu);
   while (!cl->done) {
-    grpc_pollset_worker worker;
+    grpc_pollset_worker *worker = NULL;
     grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
-    grpc_pollset_work(&exec_ctx, &g_pollset, &worker,
+    grpc_pollset_work(&exec_ctx, g_pollset, &worker,
                       gpr_now(GPR_CLOCK_MONOTONIC),
                       gpr_inf_future(GPR_CLOCK_MONOTONIC));
-    gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
+    gpr_mu_unlock(g_mu);
     grpc_exec_ctx_finish(&exec_ctx);
-    gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
+    gpr_mu_lock(g_mu);
   }
-  gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
+  gpr_mu_unlock(g_mu);
 }
 
 /* Test grpc_fd. Start an upload server and client, upload a stream of
@@ -410,20 +413,20 @@
                                 void *arg /* fd_change_data */, bool success) {
   fd_change_data *fdc = arg;
 
-  gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
+  gpr_mu_lock(g_mu);
   fdc->cb_that_ran = first_read_callback;
-  grpc_pollset_kick(&g_pollset, NULL);
-  gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
+  grpc_pollset_kick(g_pollset, NULL);
+  gpr_mu_unlock(g_mu);
 }
 
 static void second_read_callback(grpc_exec_ctx *exec_ctx,
                                  void *arg /* fd_change_data */, bool success) {
   fd_change_data *fdc = arg;
 
-  gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
+  gpr_mu_lock(g_mu);
   fdc->cb_that_ran = second_read_callback;
-  grpc_pollset_kick(&g_pollset, NULL);
-  gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
+  grpc_pollset_kick(g_pollset, NULL);
+  gpr_mu_unlock(g_mu);
 }
 
 /* Test that changing the callback we use for notify_on_read actually works.
@@ -456,7 +459,7 @@
   GPR_ASSERT(fcntl(sv[1], F_SETFL, flags | O_NONBLOCK) == 0);
 
   em_fd = grpc_fd_create(sv[0], "test_grpc_fd_change");
-  grpc_pollset_add_fd(&exec_ctx, &g_pollset, em_fd);
+  grpc_pollset_add_fd(&exec_ctx, g_pollset, em_fd);
 
   /* Register the first callback, then make its FD readable */
   grpc_fd_notify_on_read(&exec_ctx, em_fd, &first_closure);
@@ -465,18 +468,18 @@
   GPR_ASSERT(result == 1);
 
   /* And now wait for it to run. */
-  gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
+  gpr_mu_lock(g_mu);
   while (a.cb_that_ran == NULL) {
-    grpc_pollset_worker worker;
-    grpc_pollset_work(&exec_ctx, &g_pollset, &worker,
+    grpc_pollset_worker *worker = NULL;
+    grpc_pollset_work(&exec_ctx, g_pollset, &worker,
                       gpr_now(GPR_CLOCK_MONOTONIC),
                       gpr_inf_future(GPR_CLOCK_MONOTONIC));
-    gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
+    gpr_mu_unlock(g_mu);
     grpc_exec_ctx_finish(&exec_ctx);
-    gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
+    gpr_mu_lock(g_mu);
   }
   GPR_ASSERT(a.cb_that_ran == first_read_callback);
-  gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
+  gpr_mu_unlock(g_mu);
 
   /* And drain the socket so we can generate a new read edge */
   result = read(sv[0], &data, 1);
@@ -489,19 +492,19 @@
   result = write(sv[1], &data, 1);
   GPR_ASSERT(result == 1);
 
-  gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
+  gpr_mu_lock(g_mu);
   while (b.cb_that_ran == NULL) {
-    grpc_pollset_worker worker;
-    grpc_pollset_work(&exec_ctx, &g_pollset, &worker,
+    grpc_pollset_worker *worker = NULL;
+    grpc_pollset_work(&exec_ctx, g_pollset, &worker,
                       gpr_now(GPR_CLOCK_MONOTONIC),
                       gpr_inf_future(GPR_CLOCK_MONOTONIC));
-    gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
+    gpr_mu_unlock(g_mu);
     grpc_exec_ctx_finish(&exec_ctx);
-    gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
+    gpr_mu_lock(g_mu);
   }
   /* Except now we verify that second_read_callback ran instead */
   GPR_ASSERT(b.cb_that_ran == second_read_callback);
-  gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
+  gpr_mu_unlock(g_mu);
 
   grpc_fd_orphan(&exec_ctx, em_fd, NULL, NULL, "d");
   grpc_exec_ctx_finish(&exec_ctx);
@@ -519,12 +522,14 @@
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   grpc_test_init(argc, argv);
   grpc_iomgr_init();
-  grpc_pollset_init(&g_pollset);
+  g_pollset = gpr_malloc(grpc_pollset_size());
+  grpc_pollset_init(g_pollset, &g_mu);
   test_grpc_fd();
   test_grpc_fd_change();
-  grpc_closure_init(&destroyed, destroy_pollset, &g_pollset);
-  grpc_pollset_shutdown(&exec_ctx, &g_pollset, &destroyed);
+  grpc_closure_init(&destroyed, destroy_pollset, g_pollset);
+  grpc_pollset_shutdown(&exec_ctx, g_pollset, &destroyed);
   grpc_exec_ctx_finish(&exec_ctx);
+  gpr_free(g_pollset);
   grpc_iomgr_shutdown();
   return 0;
 }
diff --git a/test/core/iomgr/tcp_client_posix_test.c b/test/core/iomgr/tcp_client_posix_test.c
index 9725d8a..746dfd8 100644
--- a/test/core/iomgr/tcp_client_posix_test.c
+++ b/test/core/iomgr/tcp_client_posix_test.c
@@ -40,15 +40,18 @@
 #include <unistd.h>
 
 #include <grpc/grpc.h>
+#include <grpc/support/alloc.h>
 #include <grpc/support/log.h>
 #include <grpc/support/time.h>
 
 #include "src/core/iomgr/iomgr.h"
 #include "src/core/iomgr/socket_utils_posix.h"
+#include "src/core/iomgr/timer.h"
 #include "test/core/util/test_config.h"
 
-static grpc_pollset_set g_pollset_set;
-static grpc_pollset g_pollset;
+static grpc_pollset_set *g_pollset_set;
+static gpr_mu *g_mu;
+static grpc_pollset *g_pollset;
 static int g_connections_complete = 0;
 static grpc_endpoint *g_connecting = NULL;
 
@@ -57,10 +60,10 @@
 }
 
 static void finish_connection() {
-  gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
+  gpr_mu_lock(g_mu);
   g_connections_complete++;
-  grpc_pollset_kick(&g_pollset, NULL);
-  gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
+  grpc_pollset_kick(g_pollset, NULL);
+  gpr_mu_unlock(g_mu);
 }
 
 static void must_succeed(grpc_exec_ctx *exec_ctx, void *arg, bool success) {
@@ -98,14 +101,14 @@
   GPR_ASSERT(0 == bind(svr_fd, (struct sockaddr *)&addr, addr_len));
   GPR_ASSERT(0 == listen(svr_fd, 1));
 
-  gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
+  gpr_mu_lock(g_mu);
   connections_complete_before = g_connections_complete;
-  gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
+  gpr_mu_unlock(g_mu);
 
   /* connect to it */
   GPR_ASSERT(getsockname(svr_fd, (struct sockaddr *)&addr, &addr_len) == 0);
   grpc_closure_init(&done, must_succeed, NULL);
-  grpc_tcp_client_connect(&exec_ctx, &done, &g_connecting, &g_pollset_set,
+  grpc_tcp_client_connect(&exec_ctx, &done, &g_connecting, g_pollset_set,
                           (struct sockaddr *)&addr, addr_len,
                           gpr_inf_future(GPR_CLOCK_REALTIME));
 
@@ -117,19 +120,21 @@
   GPR_ASSERT(r >= 0);
   close(r);
 
-  gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
+  gpr_mu_lock(g_mu);
 
   while (g_connections_complete == connections_complete_before) {
-    grpc_pollset_worker worker;
-    grpc_pollset_work(&exec_ctx, &g_pollset, &worker,
+    grpc_pollset_worker *worker = NULL;
+    grpc_pollset_work(&exec_ctx, g_pollset, &worker,
                       gpr_now(GPR_CLOCK_MONOTONIC),
                       GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5));
-    gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
-    grpc_exec_ctx_finish(&exec_ctx);
-    gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
+    gpr_mu_unlock(g_mu);
+    grpc_exec_ctx_flush(&exec_ctx);
+    gpr_mu_lock(g_mu);
   }
 
-  gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
+  gpr_mu_unlock(g_mu);
+
+  grpc_exec_ctx_finish(&exec_ctx);
 }
 
 void test_fails(void) {
@@ -144,118 +149,33 @@
   memset(&addr, 0, sizeof(addr));
   addr.sin_family = AF_INET;
 
-  gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
+  gpr_mu_lock(g_mu);
   connections_complete_before = g_connections_complete;
-  gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
+  gpr_mu_unlock(g_mu);
 
   /* connect to a broken address */
   grpc_closure_init(&done, must_fail, NULL);
-  grpc_tcp_client_connect(&exec_ctx, &done, &g_connecting, &g_pollset_set,
+  grpc_tcp_client_connect(&exec_ctx, &done, &g_connecting, g_pollset_set,
                           (struct sockaddr *)&addr, addr_len,
                           gpr_inf_future(GPR_CLOCK_REALTIME));
 
-  gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
+  gpr_mu_lock(g_mu);
 
   /* wait for the connection callback to finish */
   while (g_connections_complete == connections_complete_before) {
-    grpc_pollset_worker worker;
-    grpc_pollset_work(&exec_ctx, &g_pollset, &worker,
-                      gpr_now(GPR_CLOCK_MONOTONIC), test_deadline());
-    gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
-    grpc_exec_ctx_finish(&exec_ctx);
-    gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
-  }
-
-  gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
-}
-
-void test_times_out(void) {
-  struct sockaddr_in addr;
-  socklen_t addr_len = sizeof(addr);
-  int svr_fd;
-#define NUM_CLIENT_CONNECTS 100
-  int client_fd[NUM_CLIENT_CONNECTS];
-  int i;
-  int r;
-  int connections_complete_before;
-  gpr_timespec connect_deadline;
-  grpc_closure done;
-  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
-
-  gpr_log(GPR_DEBUG, "test_times_out");
-
-  memset(&addr, 0, sizeof(addr));
-  addr.sin_family = AF_INET;
-
-  /* create a dummy server */
-  svr_fd = socket(AF_INET, SOCK_STREAM, 0);
-  GPR_ASSERT(svr_fd >= 0);
-  GPR_ASSERT(0 == bind(svr_fd, (struct sockaddr *)&addr, addr_len));
-  GPR_ASSERT(0 == listen(svr_fd, 1));
-  /* Get its address */
-  GPR_ASSERT(getsockname(svr_fd, (struct sockaddr *)&addr, &addr_len) == 0);
-
-  /* tie up the listen buffer, which is somewhat arbitrarily sized. */
-  for (i = 0; i < NUM_CLIENT_CONNECTS; ++i) {
-    client_fd[i] = socket(AF_INET, SOCK_STREAM, 0);
-    grpc_set_socket_nonblocking(client_fd[i], 1);
-    do {
-      r = connect(client_fd[i], (struct sockaddr *)&addr, addr_len);
-    } while (r == -1 && errno == EINTR);
-    GPR_ASSERT(r < 0);
-    GPR_ASSERT(errno == EWOULDBLOCK || errno == EINPROGRESS);
-  }
-
-  /* connect to dummy server address */
-
-  connect_deadline = GRPC_TIMEOUT_SECONDS_TO_DEADLINE(1);
-
-  gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
-  connections_complete_before = g_connections_complete;
-  gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
-
-  grpc_closure_init(&done, must_fail, NULL);
-  grpc_tcp_client_connect(&exec_ctx, &done, &g_connecting, &g_pollset_set,
-                          (struct sockaddr *)&addr, addr_len, connect_deadline);
-
-  /* Make sure the event doesn't trigger early */
-  gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
-  for (;;) {
-    grpc_pollset_worker worker;
-    gpr_timespec now = gpr_now(connect_deadline.clock_type);
-    gpr_timespec continue_verifying_time =
-        gpr_time_from_seconds(5, GPR_TIMESPAN);
-    gpr_timespec grace_time = gpr_time_from_seconds(3, GPR_TIMESPAN);
-    gpr_timespec finish_time =
-        gpr_time_add(connect_deadline, continue_verifying_time);
-    gpr_timespec restart_verifying_time =
-        gpr_time_add(connect_deadline, grace_time);
-    int is_after_deadline = gpr_time_cmp(now, connect_deadline) > 0;
-    if (gpr_time_cmp(now, finish_time) > 0) {
-      break;
+    grpc_pollset_worker *worker = NULL;
+    gpr_timespec now = gpr_now(GPR_CLOCK_MONOTONIC);
+    gpr_timespec polling_deadline = test_deadline();
+    if (!grpc_timer_check(&exec_ctx, now, &polling_deadline)) {
+      grpc_pollset_work(&exec_ctx, g_pollset, &worker, now, polling_deadline);
     }
-    gpr_log(GPR_DEBUG, "now=%lld.%09d connect_deadline=%lld.%09d",
-            (long long)now.tv_sec, (int)now.tv_nsec,
-            (long long)connect_deadline.tv_sec, (int)connect_deadline.tv_nsec);
-    if (is_after_deadline && gpr_time_cmp(now, restart_verifying_time) <= 0) {
-      /* allow some slack before insisting that things be done */
-    } else {
-      GPR_ASSERT(g_connections_complete ==
-                 connections_complete_before + is_after_deadline);
-    }
-    grpc_pollset_work(&exec_ctx, &g_pollset, &worker,
-                      gpr_now(GPR_CLOCK_MONOTONIC),
-                      GRPC_TIMEOUT_MILLIS_TO_DEADLINE(10));
-    gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
-    grpc_exec_ctx_finish(&exec_ctx);
-    gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
+    gpr_mu_unlock(g_mu);
+    grpc_exec_ctx_flush(&exec_ctx);
+    gpr_mu_lock(g_mu);
   }
-  gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
 
-  close(svr_fd);
-  for (i = 0; i < NUM_CLIENT_CONNECTS; ++i) {
-    close(client_fd[i]);
-  }
+  gpr_mu_unlock(g_mu);
+  grpc_exec_ctx_finish(&exec_ctx);
 }
 
 static void destroy_pollset(grpc_exec_ctx *exec_ctx, void *p, bool success) {
@@ -267,18 +187,19 @@
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   grpc_test_init(argc, argv);
   grpc_init();
-  grpc_pollset_set_init(&g_pollset_set);
-  grpc_pollset_init(&g_pollset);
-  grpc_pollset_set_add_pollset(&exec_ctx, &g_pollset_set, &g_pollset);
+  g_pollset_set = grpc_pollset_set_create();
+  g_pollset = gpr_malloc(grpc_pollset_size());
+  grpc_pollset_init(g_pollset, &g_mu);
+  grpc_pollset_set_add_pollset(&exec_ctx, g_pollset_set, g_pollset);
   grpc_exec_ctx_finish(&exec_ctx);
   test_succeeds();
   gpr_log(GPR_ERROR, "End of first test");
   test_fails();
-  test_times_out();
-  grpc_pollset_set_destroy(&g_pollset_set);
-  grpc_closure_init(&destroyed, destroy_pollset, &g_pollset);
-  grpc_pollset_shutdown(&exec_ctx, &g_pollset, &destroyed);
+  grpc_pollset_set_destroy(g_pollset_set);
+  grpc_closure_init(&destroyed, destroy_pollset, g_pollset);
+  grpc_pollset_shutdown(&exec_ctx, g_pollset, &destroyed);
   grpc_exec_ctx_finish(&exec_ctx);
   grpc_shutdown();
+  gpr_free(g_pollset);
   return 0;
 }
diff --git a/test/core/iomgr/tcp_posix_test.c b/test/core/iomgr/tcp_posix_test.c
index d290c6b..4351642 100644
--- a/test/core/iomgr/tcp_posix_test.c
+++ b/test/core/iomgr/tcp_posix_test.c
@@ -36,8 +36,8 @@
 #include <errno.h>
 #include <fcntl.h>
 #include <string.h>
-#include <sys/types.h>
 #include <sys/socket.h>
+#include <sys/types.h>
 #include <unistd.h>
 
 #include <grpc/grpc.h>
@@ -45,10 +45,11 @@
 #include <grpc/support/log.h>
 #include <grpc/support/time.h>
 #include <grpc/support/useful.h>
-#include "test/core/util/test_config.h"
 #include "test/core/iomgr/endpoint_tests.h"
+#include "test/core/util/test_config.h"
 
-static grpc_pollset g_pollset;
+static gpr_mu *g_mu;
+static grpc_pollset *g_pollset;
 
 /*
    General test notes:
@@ -145,7 +146,7 @@
 
   GPR_ASSERT(success);
 
-  gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
+  gpr_mu_lock(g_mu);
   current_data = state->read_bytes % 256;
   read_bytes = count_slices(state->incoming.slices, state->incoming.count,
                             &current_data);
@@ -153,10 +154,10 @@
   gpr_log(GPR_INFO, "Read %d bytes of %d", read_bytes,
           state->target_read_bytes);
   if (state->read_bytes >= state->target_read_bytes) {
-    gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
+    gpr_mu_unlock(g_mu);
   } else {
     grpc_endpoint_read(exec_ctx, state->ep, &state->incoming, &state->read_cb);
-    gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
+    gpr_mu_unlock(g_mu);
   }
 }
 
@@ -175,7 +176,7 @@
   create_sockets(sv);
 
   ep = grpc_tcp_create(grpc_fd_create(sv[1], "read_test"), slice_size, "test");
-  grpc_endpoint_add_to_pollset(&exec_ctx, ep, &g_pollset);
+  grpc_endpoint_add_to_pollset(&exec_ctx, ep, g_pollset);
 
   written_bytes = fill_socket_partial(sv[0], num_bytes);
   gpr_log(GPR_INFO, "Wrote %d bytes", written_bytes);
@@ -188,17 +189,17 @@
 
   grpc_endpoint_read(&exec_ctx, ep, &state.incoming, &state.read_cb);
 
-  gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
+  gpr_mu_lock(g_mu);
   while (state.read_bytes < state.target_read_bytes) {
-    grpc_pollset_worker worker;
-    grpc_pollset_work(&exec_ctx, &g_pollset, &worker,
+    grpc_pollset_worker *worker = NULL;
+    grpc_pollset_work(&exec_ctx, g_pollset, &worker,
                       gpr_now(GPR_CLOCK_MONOTONIC), deadline);
-    gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
+    gpr_mu_unlock(g_mu);
     grpc_exec_ctx_finish(&exec_ctx);
-    gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
+    gpr_mu_lock(g_mu);
   }
   GPR_ASSERT(state.read_bytes == state.target_read_bytes);
-  gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
+  gpr_mu_unlock(g_mu);
 
   gpr_slice_buffer_destroy(&state.incoming);
   grpc_endpoint_destroy(&exec_ctx, ep);
@@ -221,7 +222,7 @@
 
   ep = grpc_tcp_create(grpc_fd_create(sv[1], "large_read_test"), slice_size,
                        "test");
-  grpc_endpoint_add_to_pollset(&exec_ctx, ep, &g_pollset);
+  grpc_endpoint_add_to_pollset(&exec_ctx, ep, g_pollset);
 
   written_bytes = fill_socket(sv[0]);
   gpr_log(GPR_INFO, "Wrote %d bytes", written_bytes);
@@ -234,17 +235,17 @@
 
   grpc_endpoint_read(&exec_ctx, ep, &state.incoming, &state.read_cb);
 
-  gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
+  gpr_mu_lock(g_mu);
   while (state.read_bytes < state.target_read_bytes) {
-    grpc_pollset_worker worker;
-    grpc_pollset_work(&exec_ctx, &g_pollset, &worker,
+    grpc_pollset_worker *worker = NULL;
+    grpc_pollset_work(&exec_ctx, g_pollset, &worker,
                       gpr_now(GPR_CLOCK_MONOTONIC), deadline);
-    gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
+    gpr_mu_unlock(g_mu);
     grpc_exec_ctx_finish(&exec_ctx);
-    gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
+    gpr_mu_lock(g_mu);
   }
   GPR_ASSERT(state.read_bytes == state.target_read_bytes);
-  gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
+  gpr_mu_unlock(g_mu);
 
   gpr_slice_buffer_destroy(&state.incoming);
   grpc_endpoint_destroy(&exec_ctx, ep);
@@ -283,11 +284,11 @@
                        void *user_data /* write_socket_state */, bool success) {
   struct write_socket_state *state = (struct write_socket_state *)user_data;
   gpr_log(GPR_INFO, "Write done callback called");
-  gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
+  gpr_mu_lock(g_mu);
   gpr_log(GPR_INFO, "Signalling write done");
   state->write_done = 1;
-  grpc_pollset_kick(&g_pollset, NULL);
-  gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
+  grpc_pollset_kick(g_pollset, NULL);
+  gpr_mu_unlock(g_mu);
 }
 
 void drain_socket_blocking(int fd, size_t num_bytes, size_t read_size) {
@@ -303,12 +304,12 @@
   GPR_ASSERT(fcntl(fd, F_SETFL, flags & ~O_NONBLOCK) == 0);
 
   for (;;) {
-    grpc_pollset_worker worker;
-    gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
-    grpc_pollset_work(&exec_ctx, &g_pollset, &worker,
+    grpc_pollset_worker *worker = NULL;
+    gpr_mu_lock(g_mu);
+    grpc_pollset_work(&exec_ctx, g_pollset, &worker,
                       gpr_now(GPR_CLOCK_MONOTONIC),
                       GRPC_TIMEOUT_MILLIS_TO_DEADLINE(10));
-    gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
+    gpr_mu_unlock(g_mu);
     grpc_exec_ctx_finish(&exec_ctx);
     do {
       bytes_read =
@@ -350,7 +351,7 @@
 
   ep = grpc_tcp_create(grpc_fd_create(sv[1], "write_test"),
                        GRPC_TCP_DEFAULT_READ_SLICE_SIZE, "test");
-  grpc_endpoint_add_to_pollset(&exec_ctx, ep, &g_pollset);
+  grpc_endpoint_add_to_pollset(&exec_ctx, ep, g_pollset);
 
   state.ep = ep;
   state.write_done = 0;
@@ -363,19 +364,19 @@
 
   grpc_endpoint_write(&exec_ctx, ep, &outgoing, &write_done_closure);
   drain_socket_blocking(sv[0], num_bytes, num_bytes);
-  gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
+  gpr_mu_lock(g_mu);
   for (;;) {
-    grpc_pollset_worker worker;
+    grpc_pollset_worker *worker = NULL;
     if (state.write_done) {
       break;
     }
-    grpc_pollset_work(&exec_ctx, &g_pollset, &worker,
+    grpc_pollset_work(&exec_ctx, g_pollset, &worker,
                       gpr_now(GPR_CLOCK_MONOTONIC), deadline);
-    gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
+    gpr_mu_unlock(g_mu);
     grpc_exec_ctx_finish(&exec_ctx);
-    gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
+    gpr_mu_lock(g_mu);
   }
-  gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
+  gpr_mu_unlock(g_mu);
 
   gpr_slice_buffer_destroy(&outgoing);
   grpc_endpoint_destroy(&exec_ctx, ep);
@@ -386,7 +387,7 @@
 void on_fd_released(grpc_exec_ctx *exec_ctx, void *arg, bool success) {
   int *done = arg;
   *done = 1;
-  grpc_pollset_kick(&g_pollset, NULL);
+  grpc_pollset_kick(g_pollset, NULL);
 }
 
 /* Do a read_test, then release fd and try to read/write again. Verify that
@@ -410,7 +411,7 @@
 
   ep = grpc_tcp_create(grpc_fd_create(sv[1], "read_test"), slice_size, "test");
   GPR_ASSERT(grpc_tcp_fd(ep) == sv[1] && sv[1] >= 0);
-  grpc_endpoint_add_to_pollset(&exec_ctx, ep, &g_pollset);
+  grpc_endpoint_add_to_pollset(&exec_ctx, ep, g_pollset);
 
   written_bytes = fill_socket_partial(sv[0], num_bytes);
   gpr_log(GPR_INFO, "Wrote %d bytes", written_bytes);
@@ -423,27 +424,27 @@
 
   grpc_endpoint_read(&exec_ctx, ep, &state.incoming, &state.read_cb);
 
-  gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
+  gpr_mu_lock(g_mu);
   while (state.read_bytes < state.target_read_bytes) {
-    grpc_pollset_worker worker;
-    grpc_pollset_work(&exec_ctx, &g_pollset, &worker,
+    grpc_pollset_worker *worker = NULL;
+    grpc_pollset_work(&exec_ctx, g_pollset, &worker,
                       gpr_now(GPR_CLOCK_MONOTONIC), deadline);
-    gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
+    gpr_mu_unlock(g_mu);
     grpc_exec_ctx_finish(&exec_ctx);
-    gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
+    gpr_mu_lock(g_mu);
   }
   GPR_ASSERT(state.read_bytes == state.target_read_bytes);
-  gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
+  gpr_mu_unlock(g_mu);
 
   gpr_slice_buffer_destroy(&state.incoming);
   grpc_tcp_destroy_and_release_fd(&exec_ctx, ep, &fd, &fd_released_cb);
-  gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
+  gpr_mu_lock(g_mu);
   while (!fd_released_done) {
-    grpc_pollset_worker worker;
-    grpc_pollset_work(&exec_ctx, &g_pollset, &worker,
+    grpc_pollset_worker *worker = NULL;
+    grpc_pollset_work(&exec_ctx, g_pollset, &worker,
                       gpr_now(GPR_CLOCK_MONOTONIC), deadline);
   }
-  gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
+  gpr_mu_unlock(g_mu);
   GPR_ASSERT(fd_released_done == 1);
   GPR_ASSERT(fd == sv[1]);
   grpc_exec_ctx_finish(&exec_ctx);
@@ -491,8 +492,8 @@
                                 slice_size, "test");
   f.server_ep = grpc_tcp_create(grpc_fd_create(sv[1], "fixture:server"),
                                 slice_size, "test");
-  grpc_endpoint_add_to_pollset(&exec_ctx, f.client_ep, &g_pollset);
-  grpc_endpoint_add_to_pollset(&exec_ctx, f.server_ep, &g_pollset);
+  grpc_endpoint_add_to_pollset(&exec_ctx, f.client_ep, g_pollset);
+  grpc_endpoint_add_to_pollset(&exec_ctx, f.server_ep, g_pollset);
 
   grpc_exec_ctx_finish(&exec_ctx);
 
@@ -512,13 +513,15 @@
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   grpc_test_init(argc, argv);
   grpc_init();
-  grpc_pollset_init(&g_pollset);
+  g_pollset = gpr_malloc(grpc_pollset_size());
+  grpc_pollset_init(g_pollset, &g_mu);
   run_tests();
-  grpc_endpoint_tests(configs[0], &g_pollset);
-  grpc_closure_init(&destroyed, destroy_pollset, &g_pollset);
-  grpc_pollset_shutdown(&exec_ctx, &g_pollset, &destroyed);
+  grpc_endpoint_tests(configs[0], g_pollset, g_mu);
+  grpc_closure_init(&destroyed, destroy_pollset, g_pollset);
+  grpc_pollset_shutdown(&exec_ctx, g_pollset, &destroyed);
   grpc_exec_ctx_finish(&exec_ctx);
   grpc_shutdown();
+  gpr_free(g_pollset);
 
   return 0;
 }
diff --git a/test/core/iomgr/tcp_server_posix_test.c b/test/core/iomgr/tcp_server_posix_test.c
index 272d97b..7933468 100644
--- a/test/core/iomgr/tcp_server_posix_test.c
+++ b/test/core/iomgr/tcp_server_posix_test.c
@@ -32,24 +32,28 @@
  */
 
 #include "src/core/iomgr/tcp_server.h"
-#include "src/core/iomgr/iomgr.h"
-#include "src/core/iomgr/sockaddr_utils.h"
+
+#include <errno.h>
+#include <netinet/in.h>
+#include <string.h>
+#include <sys/socket.h>
+#include <unistd.h>
+
 #include <grpc/grpc.h>
+#include <grpc/support/alloc.h>
 #include <grpc/support/log.h>
 #include <grpc/support/sync.h>
 #include <grpc/support/time.h>
+
+#include "src/core/iomgr/iomgr.h"
+#include "src/core/iomgr/sockaddr_utils.h"
 #include "test/core/util/port.h"
 #include "test/core/util/test_config.h"
 
-#include <errno.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <string.h>
-#include <unistd.h>
-
 #define LOG_TEST(x) gpr_log(GPR_INFO, "%s", #x)
 
-static grpc_pollset g_pollset;
+static gpr_mu *g_mu;
+static grpc_pollset *g_pollset;
 static int g_nconnects = 0;
 
 typedef struct on_connect_result {
@@ -113,11 +117,11 @@
   grpc_endpoint_shutdown(exec_ctx, tcp);
   grpc_endpoint_destroy(exec_ctx, tcp);
 
-  gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
+  gpr_mu_lock(g_mu);
   on_connect_result_set(&g_result, acceptor);
   g_nconnects++;
-  grpc_pollset_kick(&g_pollset, NULL);
-  gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
+  grpc_pollset_kick(g_pollset, NULL);
+  gpr_mu_unlock(g_mu);
 }
 
 static void test_no_op(void) {
@@ -174,7 +178,7 @@
   int clifd = socket(remote->sa_family, SOCK_STREAM, 0);
   int nconnects_before;
 
-  gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
+  gpr_mu_lock(g_mu);
   nconnects_before = g_nconnects;
   on_connect_result_init(&g_result);
   GPR_ASSERT(clifd >= 0);
@@ -183,19 +187,19 @@
   gpr_log(GPR_DEBUG, "wait");
   while (g_nconnects == nconnects_before &&
          gpr_time_cmp(deadline, gpr_now(deadline.clock_type)) > 0) {
-    grpc_pollset_worker worker;
-    grpc_pollset_work(exec_ctx, &g_pollset, &worker,
+    grpc_pollset_worker *worker = NULL;
+    grpc_pollset_work(exec_ctx, g_pollset, &worker,
                       gpr_now(GPR_CLOCK_MONOTONIC), deadline);
-    gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
+    gpr_mu_unlock(g_mu);
     grpc_exec_ctx_finish(exec_ctx);
-    gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
+    gpr_mu_lock(g_mu);
   }
   gpr_log(GPR_DEBUG, "wait done");
   GPR_ASSERT(g_nconnects == nconnects_before + 1);
   close(clifd);
   *result = g_result;
 
-  gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
+  gpr_mu_unlock(g_mu);
 }
 
 /* Tests a tcp server with multiple ports. TODO(daniel-j-born): Multiple fds for
@@ -210,7 +214,6 @@
   unsigned svr1_fd_count;
   int svr1_port;
   grpc_tcp_server *s = grpc_tcp_server_create(NULL);
-  grpc_pollset *pollsets[1];
   unsigned i;
   server_weak_ref weak_ref;
   server_weak_ref_init(&weak_ref);
@@ -259,8 +262,7 @@
     }
   }
 
-  pollsets[0] = &g_pollset;
-  grpc_tcp_server_start(&exec_ctx, s, pollsets, 1, on_connect, NULL);
+  grpc_tcp_server_start(&exec_ctx, s, &g_pollset, 1, on_connect, NULL);
 
   for (i = 0; i < n; i++) {
     on_connect_result result;
@@ -312,7 +314,8 @@
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   grpc_test_init(argc, argv);
   grpc_init();
-  grpc_pollset_init(&g_pollset);
+  g_pollset = gpr_malloc(grpc_pollset_size());
+  grpc_pollset_init(g_pollset, &g_mu);
 
   test_no_op();
   test_no_op_with_start();
@@ -321,9 +324,10 @@
   test_connect(1);
   test_connect(10);
 
-  grpc_closure_init(&destroyed, destroy_pollset, &g_pollset);
-  grpc_pollset_shutdown(&exec_ctx, &g_pollset, &destroyed);
+  grpc_closure_init(&destroyed, destroy_pollset, g_pollset);
+  grpc_pollset_shutdown(&exec_ctx, g_pollset, &destroyed);
   grpc_exec_ctx_finish(&exec_ctx);
   grpc_shutdown();
+  gpr_free(g_pollset);
   return 0;
 }
diff --git a/test/core/iomgr/timer_list_test.c b/test/core/iomgr/timer_list_test.c
index 15de87c..7a21fdd 100644
--- a/test/core/iomgr/timer_list_test.c
+++ b/test/core/iomgr/timer_list_test.c
@@ -35,7 +35,6 @@
 
 #include <string.h>
 
-#include "src/core/iomgr/timer_internal.h"
 #include <grpc/support/log.h>
 #include "test/core/util/test_config.h"
 
@@ -72,20 +71,19 @@
   }
 
   /* collect timers.  Only the first batch should be ready. */
-  GPR_ASSERT(10 == grpc_timer_check(&exec_ctx,
-                                    gpr_time_add(start, gpr_time_from_millis(
-                                                            500, GPR_TIMESPAN)),
-                                    NULL));
+  GPR_ASSERT(grpc_timer_check(
+      &exec_ctx, gpr_time_add(start, gpr_time_from_millis(500, GPR_TIMESPAN)),
+      NULL));
   grpc_exec_ctx_finish(&exec_ctx);
   for (i = 0; i < 20; i++) {
     GPR_ASSERT(cb_called[i][1] == (i < 10));
     GPR_ASSERT(cb_called[i][0] == 0);
   }
 
-  GPR_ASSERT(0 == grpc_timer_check(&exec_ctx,
-                                   gpr_time_add(start, gpr_time_from_millis(
-                                                           600, GPR_TIMESPAN)),
-                                   NULL));
+  GPR_ASSERT(!grpc_timer_check(
+                 &exec_ctx,
+                 gpr_time_add(start, gpr_time_from_millis(600, GPR_TIMESPAN)),
+                 NULL));
   grpc_exec_ctx_finish(&exec_ctx);
   for (i = 0; i < 30; i++) {
     GPR_ASSERT(cb_called[i][1] == (i < 10));
@@ -93,20 +91,19 @@
   }
 
   /* collect the rest of the timers */
-  GPR_ASSERT(10 == grpc_timer_check(
-                       &exec_ctx, gpr_time_add(start, gpr_time_from_millis(
-                                                          1500, GPR_TIMESPAN)),
-                       NULL));
+  GPR_ASSERT(grpc_timer_check(
+      &exec_ctx, gpr_time_add(start, gpr_time_from_millis(1500, GPR_TIMESPAN)),
+      NULL));
   grpc_exec_ctx_finish(&exec_ctx);
   for (i = 0; i < 30; i++) {
     GPR_ASSERT(cb_called[i][1] == (i < 20));
     GPR_ASSERT(cb_called[i][0] == 0);
   }
 
-  GPR_ASSERT(0 == grpc_timer_check(&exec_ctx,
-                                   gpr_time_add(start, gpr_time_from_millis(
-                                                           1600, GPR_TIMESPAN)),
-                                   NULL));
+  GPR_ASSERT(!grpc_timer_check(
+                 &exec_ctx,
+                 gpr_time_add(start, gpr_time_from_millis(1600, GPR_TIMESPAN)),
+                 NULL));
   for (i = 0; i < 30; i++) {
     GPR_ASSERT(cb_called[i][1] == (i < 20));
     GPR_ASSERT(cb_called[i][0] == 0);
diff --git a/test/core/iomgr/workqueue_test.c b/test/core/iomgr/workqueue_test.c
index 500170b..8a1faf6 100644
--- a/test/core/iomgr/workqueue_test.c
+++ b/test/core/iomgr/workqueue_test.c
@@ -34,18 +34,20 @@
 #include "src/core/iomgr/workqueue.h"
 
 #include <grpc/grpc.h>
+#include <grpc/support/alloc.h>
 #include <grpc/support/log.h>
 
 #include "test/core/util/test_config.h"
 
-static grpc_pollset g_pollset;
+static gpr_mu *g_mu;
+static grpc_pollset *g_pollset;
 
 static void must_succeed(grpc_exec_ctx *exec_ctx, void *p, bool success) {
   GPR_ASSERT(success == 1);
-  gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
+  gpr_mu_lock(g_mu);
   *(int *)p = 1;
-  grpc_pollset_kick(&g_pollset, NULL);
-  gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
+  grpc_pollset_kick(g_pollset, NULL);
+  gpr_mu_unlock(g_mu);
 }
 
 static void test_ref_unref(void) {
@@ -63,17 +65,17 @@
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   grpc_workqueue *wq = grpc_workqueue_create(&exec_ctx);
   gpr_timespec deadline = GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5);
-  grpc_pollset_worker worker;
+  grpc_pollset_worker *worker = NULL;
   grpc_closure_init(&c, must_succeed, &done);
 
   grpc_workqueue_push(wq, &c, 1);
-  grpc_workqueue_add_to_pollset(&exec_ctx, wq, &g_pollset);
+  grpc_workqueue_add_to_pollset(&exec_ctx, wq, g_pollset);
 
-  gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
+  gpr_mu_lock(g_mu);
   GPR_ASSERT(!done);
-  grpc_pollset_work(&exec_ctx, &g_pollset, &worker,
-                    gpr_now(deadline.clock_type), deadline);
-  gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
+  grpc_pollset_work(&exec_ctx, g_pollset, &worker, gpr_now(deadline.clock_type),
+                    deadline);
+  gpr_mu_unlock(g_mu);
   grpc_exec_ctx_finish(&exec_ctx);
   GPR_ASSERT(done);
 
@@ -87,18 +89,18 @@
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   grpc_workqueue *wq = grpc_workqueue_create(&exec_ctx);
   gpr_timespec deadline = GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5);
-  grpc_pollset_worker worker;
+  grpc_pollset_worker *worker = NULL;
   grpc_closure_init(&c, must_succeed, &done);
 
   grpc_exec_ctx_enqueue(&exec_ctx, &c, true, NULL);
   grpc_workqueue_flush(&exec_ctx, wq);
-  grpc_workqueue_add_to_pollset(&exec_ctx, wq, &g_pollset);
+  grpc_workqueue_add_to_pollset(&exec_ctx, wq, g_pollset);
 
-  gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
+  gpr_mu_lock(g_mu);
   GPR_ASSERT(!done);
-  grpc_pollset_work(&exec_ctx, &g_pollset, &worker,
-                    gpr_now(deadline.clock_type), deadline);
-  gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
+  grpc_pollset_work(&exec_ctx, g_pollset, &worker, gpr_now(deadline.clock_type),
+                    deadline);
+  gpr_mu_unlock(g_mu);
   grpc_exec_ctx_finish(&exec_ctx);
   GPR_ASSERT(done);
 
@@ -115,15 +117,18 @@
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   grpc_test_init(argc, argv);
   grpc_init();
-  grpc_pollset_init(&g_pollset);
+  g_pollset = gpr_malloc(grpc_pollset_size());
+  grpc_pollset_init(g_pollset, &g_mu);
 
   test_ref_unref();
   test_add_closure();
   test_flush();
 
-  grpc_closure_init(&destroyed, destroy_pollset, &g_pollset);
-  grpc_pollset_shutdown(&exec_ctx, &g_pollset, &destroyed);
+  grpc_closure_init(&destroyed, destroy_pollset, g_pollset);
+  grpc_pollset_shutdown(&exec_ctx, g_pollset, &destroyed);
   grpc_exec_ctx_finish(&exec_ctx);
   grpc_shutdown();
+
+  gpr_free(g_pollset);
   return 0;
 }
diff --git a/test/core/security/base64_test.c b/test/core/security/b64_test.c
similarity index 98%
rename from test/core/security/base64_test.c
rename to test/core/security/b64_test.c
index e656d4c..772514e 100644
--- a/test/core/security/base64_test.c
+++ b/test/core/security/b64_test.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,7 +31,7 @@
  *
  */
 
-#include "src/core/security/base64.h"
+#include "src/core/security/b64.h"
 
 #include <string.h>
 
diff --git a/test/core/security/create_jwt.c b/test/core/security/create_jwt.c
index 237dc9a..4c0cf43 100644
--- a/test/core/security/create_jwt.c
+++ b/test/core/security/create_jwt.c
@@ -36,7 +36,7 @@
 
 #include "src/core/security/credentials.h"
 #include "src/core/security/json_token.h"
-#include "src/core/support/file.h"
+#include "src/core/support/load_file.h"
 
 #include <grpc/support/alloc.h>
 #include <grpc/support/cmdline.h>
diff --git a/test/core/security/credentials_test.c b/test/core/security/credentials_test.c
index 8a210bb..98133ef 100644
--- a/test/core/security/credentials_test.c
+++ b/test/core/security/credentials_test.c
@@ -32,25 +32,24 @@
  */
 
 #include <grpc/support/port_platform.h>
+
 #include "src/core/security/credentials.h"
 
+#include <openssl/rsa.h>
 #include <stdlib.h>
 #include <string.h>
 
-#include "src/core/httpcli/httpcli.h"
-#include "src/core/security/json_token.h"
-#include "src/core/support/env.h"
-#include "src/core/support/file.h"
-#include "src/core/support/string.h"
-
-#include "test/core/util/test_config.h"
-
 #include <grpc/support/alloc.h>
 #include <grpc/support/log.h>
 #include <grpc/support/string_util.h>
 #include <grpc/support/time.h>
 
-#include <openssl/rsa.h>
+#include "src/core/httpcli/httpcli.h"
+#include "src/core/security/json_token.h"
+#include "src/core/support/env.h"
+#include "src/core/support/tmpfile.h"
+#include "src/core/support/string.h"
+#include "test/core/util/test_config.h"
 
 /* -- Mock channel credentials. -- */
 
diff --git a/test/core/security/fetch_oauth2.c b/test/core/security/fetch_oauth2.c
index ee1178c..87b54f1 100644
--- a/test/core/security/fetch_oauth2.c
+++ b/test/core/security/fetch_oauth2.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -43,7 +43,7 @@
 #include <grpc/support/sync.h>
 
 #include "src/core/security/credentials.h"
-#include "src/core/support/file.h"
+#include "src/core/support/load_file.h"
 #include "test/core/security/oauth2_utils.h"
 
 static grpc_call_credentials *create_refresh_token_creds(
diff --git a/test/core/security/json_token_test.c b/test/core/security/json_token_test.c
index 7c01a9c..4d80c16 100644
--- a/test/core/security/json_token_test.c
+++ b/test/core/security/json_token_test.c
@@ -33,16 +33,17 @@
 
 #include "src/core/security/json_token.h"
 
+#include <openssl/evp.h>
 #include <string.h>
 
-#include "src/core/security/base64.h"
 #include <grpc/grpc_security.h>
 #include <grpc/support/alloc.h>
 #include <grpc/support/log.h>
 #include <grpc/support/slice.h>
-#include "test/core/util/test_config.h"
+
 #include "src/core/json/json.h"
-#include <openssl/evp.h>
+#include "src/core/security/b64.h"
+#include "test/core/util/test_config.h"
 
 /* This JSON key was generated with the GCE console and revoked immediately.
    The identifiers have been changed as well.
diff --git a/test/core/security/jwt_verifier_test.c b/test/core/security/jwt_verifier_test.c
index f396398..f6ec9e1 100644
--- a/test/core/security/jwt_verifier_test.c
+++ b/test/core/security/jwt_verifier_test.c
@@ -36,7 +36,7 @@
 #include <string.h>
 
 #include "src/core/httpcli/httpcli.h"
-#include "src/core/security/base64.h"
+#include "src/core/security/b64.h"
 #include "src/core/security/json_token.h"
 #include "test/core/util/test_config.h"
 
diff --git a/test/core/security/oauth2_utils.c b/test/core/security/oauth2_utils.c
index 55ac31e..9b70aff 100644
--- a/test/core/security/oauth2_utils.c
+++ b/test/core/security/oauth2_utils.c
@@ -45,7 +45,8 @@
 #include "src/core/security/credentials.h"
 
 typedef struct {
-  grpc_pollset pollset;
+  gpr_mu *mu;
+  grpc_pollset *pollset;
   int is_done;
   char *token;
 } oauth2_request;
@@ -66,11 +67,11 @@
            GPR_SLICE_LENGTH(token_slice));
     token[GPR_SLICE_LENGTH(token_slice)] = '\0';
   }
-  gpr_mu_lock(GRPC_POLLSET_MU(&request->pollset));
+  gpr_mu_lock(request->mu);
   request->is_done = 1;
   request->token = token;
-  grpc_pollset_kick(&request->pollset, NULL);
-  gpr_mu_unlock(GRPC_POLLSET_MU(&request->pollset));
+  grpc_pollset_kick(request->pollset, NULL);
+  gpr_mu_unlock(request->mu);
 }
 
 static void do_nothing(grpc_exec_ctx *exec_ctx, void *unused, bool success) {}
@@ -82,28 +83,30 @@
   grpc_closure do_nothing_closure;
   grpc_auth_metadata_context null_ctx = {"", "", NULL, NULL};
 
-  grpc_pollset_init(&request.pollset);
+  request.pollset = gpr_malloc(grpc_pollset_size());
+  grpc_pollset_init(request.pollset, &request.mu);
   request.is_done = 0;
 
   grpc_closure_init(&do_nothing_closure, do_nothing, NULL);
 
-  grpc_call_credentials_get_request_metadata(&exec_ctx, creds, &request.pollset,
+  grpc_call_credentials_get_request_metadata(&exec_ctx, creds, request.pollset,
                                              null_ctx, on_oauth2_response,
                                              &request);
 
   grpc_exec_ctx_finish(&exec_ctx);
 
-  gpr_mu_lock(GRPC_POLLSET_MU(&request.pollset));
+  gpr_mu_lock(request.mu);
   while (!request.is_done) {
-    grpc_pollset_worker worker;
-    grpc_pollset_work(&exec_ctx, &request.pollset, &worker,
+    grpc_pollset_worker *worker = NULL;
+    grpc_pollset_work(&exec_ctx, request.pollset, &worker,
                       gpr_now(GPR_CLOCK_MONOTONIC),
                       gpr_inf_future(GPR_CLOCK_MONOTONIC));
   }
-  gpr_mu_unlock(GRPC_POLLSET_MU(&request.pollset));
+  gpr_mu_unlock(request.mu);
 
-  grpc_pollset_shutdown(&exec_ctx, &request.pollset, &do_nothing_closure);
+  grpc_pollset_shutdown(&exec_ctx, request.pollset, &do_nothing_closure);
   grpc_exec_ctx_finish(&exec_ctx);
-  grpc_pollset_destroy(&request.pollset);
+  grpc_pollset_destroy(request.pollset);
+  gpr_free(request.pollset);
   return request.token;
 }
diff --git a/test/core/security/print_google_default_creds_token.c b/test/core/security/print_google_default_creds_token.c
index 50fe61c..09673f3 100644
--- a/test/core/security/print_google_default_creds_token.c
+++ b/test/core/security/print_google_default_creds_token.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -34,8 +34,6 @@
 #include <stdio.h>
 #include <string.h>
 
-#include "src/core/security/credentials.h"
-#include "src/core/support/string.h"
 #include <grpc/grpc.h>
 #include <grpc/grpc_security.h>
 #include <grpc/support/alloc.h>
@@ -44,8 +42,12 @@
 #include <grpc/support/slice.h>
 #include <grpc/support/sync.h>
 
+#include "src/core/security/credentials.h"
+#include "src/core/support/string.h"
+
 typedef struct {
-  grpc_pollset pollset;
+  gpr_mu *mu;
+  grpc_pollset *pollset;
   int is_done;
 } synchronizer;
 
@@ -62,10 +64,10 @@
     printf("\nGot token: %s\n\n", token);
     gpr_free(token);
   }
-  gpr_mu_lock(GRPC_POLLSET_MU(&sync->pollset));
+  gpr_mu_lock(sync->mu);
   sync->is_done = 1;
-  grpc_pollset_kick(&sync->pollset, NULL);
-  gpr_mu_unlock(GRPC_POLLSET_MU(&sync->pollset));
+  grpc_pollset_kick(sync->pollset, NULL);
+  gpr_mu_unlock(sync->mu);
 }
 
 int main(int argc, char **argv) {
@@ -91,26 +93,30 @@
     goto end;
   }
 
-  grpc_pollset_init(&sync.pollset);
+  sync.pollset = gpr_malloc(grpc_pollset_size());
+  grpc_pollset_init(sync.pollset, &sync.mu);
   sync.is_done = 0;
 
   grpc_call_credentials_get_request_metadata(
       &exec_ctx, ((grpc_composite_channel_credentials *)creds)->call_creds,
-      &sync.pollset, context, on_metadata_response, &sync);
+      sync.pollset, context, on_metadata_response, &sync);
 
-  gpr_mu_lock(GRPC_POLLSET_MU(&sync.pollset));
+  gpr_mu_lock(sync.mu);
   while (!sync.is_done) {
-    grpc_pollset_worker worker;
-    grpc_pollset_work(&exec_ctx, &sync.pollset, &worker,
+    grpc_pollset_worker *worker = NULL;
+    grpc_pollset_work(&exec_ctx, sync.pollset, &worker,
                       gpr_now(GPR_CLOCK_MONOTONIC),
                       gpr_inf_future(GPR_CLOCK_MONOTONIC));
-    gpr_mu_unlock(GRPC_POLLSET_MU(&sync.pollset));
-    grpc_exec_ctx_finish(&exec_ctx);
-    gpr_mu_lock(GRPC_POLLSET_MU(&sync.pollset));
+    gpr_mu_unlock(sync.mu);
+    grpc_exec_ctx_flush(&exec_ctx);
+    gpr_mu_lock(sync.mu);
   }
-  gpr_mu_unlock(GRPC_POLLSET_MU(&sync.pollset));
+  gpr_mu_unlock(sync.mu);
+
+  grpc_exec_ctx_finish(&exec_ctx);
 
   grpc_channel_credentials_release(creds);
+  gpr_free(sync.pollset);
 
 end:
   gpr_cmdline_destroy(cl);
diff --git a/test/core/security/secure_endpoint_test.c b/test/core/security/secure_endpoint_test.c
index fb4bd30..0e8c38a 100644
--- a/test/core/security/secure_endpoint_test.c
+++ b/test/core/security/secure_endpoint_test.c
@@ -36,16 +36,17 @@
 #include <fcntl.h>
 #include <sys/types.h>
 
-#include "src/core/security/secure_endpoint.h"
-#include "src/core/iomgr/endpoint_pair.h"
-#include "src/core/iomgr/iomgr.h"
 #include <grpc/grpc.h>
 #include <grpc/support/alloc.h>
 #include <grpc/support/log.h>
-#include "test/core/util/test_config.h"
+#include "src/core/iomgr/endpoint_pair.h"
+#include "src/core/iomgr/iomgr.h"
+#include "src/core/security/secure_endpoint.h"
 #include "src/core/tsi/fake_transport_security.h"
+#include "test/core/util/test_config.h"
 
-static grpc_pollset g_pollset;
+static gpr_mu *g_mu;
+static grpc_pollset *g_pollset;
 
 static grpc_endpoint_test_fixture secure_endpoint_create_fixture_tcp_socketpair(
     size_t slice_size, gpr_slice *leftover_slices, size_t leftover_nslices) {
@@ -56,8 +57,8 @@
   grpc_endpoint_pair tcp;
 
   tcp = grpc_iomgr_create_endpoint_pair("fixture", slice_size);
-  grpc_endpoint_add_to_pollset(&exec_ctx, tcp.client, &g_pollset);
-  grpc_endpoint_add_to_pollset(&exec_ctx, tcp.server, &g_pollset);
+  grpc_endpoint_add_to_pollset(&exec_ctx, tcp.client, g_pollset);
+  grpc_endpoint_add_to_pollset(&exec_ctx, tcp.server, g_pollset);
 
   if (leftover_nslices == 0) {
     f.client_ep =
@@ -181,13 +182,16 @@
   grpc_test_init(argc, argv);
 
   grpc_init();
-  grpc_pollset_init(&g_pollset);
-  grpc_endpoint_tests(configs[0], &g_pollset);
+  g_pollset = gpr_malloc(grpc_pollset_size());
+  grpc_pollset_init(g_pollset, &g_mu);
+  grpc_endpoint_tests(configs[0], g_pollset, g_mu);
   test_leftover(configs[1], 1);
-  grpc_closure_init(&destroyed, destroy_pollset, &g_pollset);
-  grpc_pollset_shutdown(&exec_ctx, &g_pollset, &destroyed);
+  grpc_closure_init(&destroyed, destroy_pollset, g_pollset);
+  grpc_pollset_shutdown(&exec_ctx, g_pollset, &destroyed);
   grpc_exec_ctx_finish(&exec_ctx);
   grpc_shutdown();
 
+  gpr_free(g_pollset);
+
   return 0;
 }
diff --git a/test/core/security/security_connector_test.c b/test/core/security/security_connector_test.c
index ee5435f..420e3a4 100644
--- a/test/core/security/security_connector_test.c
+++ b/test/core/security/security_connector_test.c
@@ -34,22 +34,21 @@
 #include <stdio.h>
 #include <string.h>
 
-#include "src/core/security/security_connector.h"
-#include "src/core/security/security_context.h"
-#include "src/core/support/env.h"
-#include "src/core/support/file.h"
-#include "src/core/support/string.h"
-#include "src/core/tsi/ssl_transport_security.h"
-#include "src/core/tsi/transport_security.h"
-#include "test/core/util/test_config.h"
-
 #include <grpc/grpc_security.h>
-
 #include <grpc/support/alloc.h>
 #include <grpc/support/log.h>
 #include <grpc/support/string_util.h>
 #include <grpc/support/useful.h>
 
+#include "src/core/security/security_connector.h"
+#include "src/core/security/security_context.h"
+#include "src/core/support/env.h"
+#include "src/core/support/tmpfile.h"
+#include "src/core/support/string.h"
+#include "src/core/tsi/ssl_transport_security.h"
+#include "src/core/tsi/transport_security.h"
+#include "test/core/util/test_config.h"
+
 static int check_transport_security_type(const grpc_auth_context *ctx) {
   grpc_auth_property_iterator it = grpc_auth_context_find_properties_by_name(
       ctx, GRPC_TRANSPORT_SECURITY_TYPE_PROPERTY_NAME);
diff --git a/test/core/security/verify_jwt.c b/test/core/security/verify_jwt.c
index 378a37f..eb86589 100644
--- a/test/core/security/verify_jwt.c
+++ b/test/core/security/verify_jwt.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -34,7 +34,6 @@
 #include <stdio.h>
 #include <string.h>
 
-#include "src/core/security/jwt_verifier.h"
 #include <grpc/grpc.h>
 #include <grpc/grpc_security.h>
 #include <grpc/support/alloc.h>
@@ -43,8 +42,11 @@
 #include <grpc/support/slice.h>
 #include <grpc/support/sync.h>
 
+#include "src/core/security/jwt_verifier.h"
+
 typedef struct {
-  grpc_pollset pollset;
+  grpc_pollset *pollset;
+  gpr_mu *mu;
   int is_done;
   int success;
 } synchronizer;
@@ -77,10 +79,10 @@
             grpc_jwt_verifier_status_to_string(status));
   }
 
-  gpr_mu_lock(GRPC_POLLSET_MU(&sync->pollset));
+  gpr_mu_lock(sync->mu);
   sync->is_done = 1;
-  grpc_pollset_kick(&sync->pollset, NULL);
-  gpr_mu_unlock(GRPC_POLLSET_MU(&sync->pollset));
+  grpc_pollset_kick(sync->pollset, NULL);
+  gpr_mu_unlock(sync->mu);
 }
 
 int main(int argc, char **argv) {
@@ -103,23 +105,26 @@
 
   grpc_init();
 
-  grpc_pollset_init(&sync.pollset);
+  sync.pollset = gpr_malloc(grpc_pollset_size());
+  grpc_pollset_init(sync.pollset, &sync.mu);
   sync.is_done = 0;
 
-  grpc_jwt_verifier_verify(&exec_ctx, verifier, &sync.pollset, jwt, aud,
+  grpc_jwt_verifier_verify(&exec_ctx, verifier, sync.pollset, jwt, aud,
                            on_jwt_verification_done, &sync);
 
-  gpr_mu_lock(GRPC_POLLSET_MU(&sync.pollset));
+  gpr_mu_lock(sync.mu);
   while (!sync.is_done) {
-    grpc_pollset_worker worker;
-    grpc_pollset_work(&exec_ctx, &sync.pollset, &worker,
+    grpc_pollset_worker *worker = NULL;
+    grpc_pollset_work(&exec_ctx, sync.pollset, &worker,
                       gpr_now(GPR_CLOCK_MONOTONIC),
                       gpr_inf_future(GPR_CLOCK_MONOTONIC));
-    gpr_mu_unlock(GRPC_POLLSET_MU(&sync.pollset));
+    gpr_mu_unlock(sync.mu);
     grpc_exec_ctx_finish(&exec_ctx);
-    gpr_mu_lock(GRPC_POLLSET_MU(&sync.pollset));
+    gpr_mu_lock(sync.mu);
   }
-  gpr_mu_unlock(GRPC_POLLSET_MU(&sync.pollset));
+  gpr_mu_unlock(sync.mu);
+
+  gpr_free(sync.pollset);
 
   grpc_jwt_verifier_destroy(verifier);
   gpr_cmdline_destroy(cl);
diff --git a/test/core/support/file_test.c b/test/core/support/load_file_test.c
similarity index 97%
rename from test/core/support/file_test.c
rename to test/core/support/load_file_test.c
index 330b217..e6ba617 100644
--- a/test/core/support/file_test.c
+++ b/test/core/support/load_file_test.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -38,7 +38,8 @@
 #include <grpc/support/log.h>
 #include <grpc/support/slice.h>
 
-#include "src/core/support/file.h"
+#include "src/core/support/load_file.h"
+#include "src/core/support/tmpfile.h"
 #include "src/core/support/string.h"
 #include "test/core/util/test_config.h"
 
diff --git a/test/core/util/port_posix.c b/test/core/util/port_posix.c
index 4b31f81..ba382d2 100644
--- a/test/core/util/port_posix.c
+++ b/test/core/util/port_posix.c
@@ -69,7 +69,8 @@
 }
 
 typedef struct freereq {
-  grpc_pollset pollset;
+  gpr_mu *mu;
+  grpc_pollset *pollset;
   int done;
 } freereq;
 
@@ -82,10 +83,10 @@
 static void freed_port_from_server(grpc_exec_ctx *exec_ctx, void *arg,
                                    const grpc_httpcli_response *response) {
   freereq *pr = arg;
-  gpr_mu_lock(GRPC_POLLSET_MU(&pr->pollset));
+  gpr_mu_lock(pr->mu);
   pr->done = 1;
-  grpc_pollset_kick(&pr->pollset, NULL);
-  gpr_mu_unlock(GRPC_POLLSET_MU(&pr->pollset));
+  grpc_pollset_kick(pr->pollset, NULL);
+  gpr_mu_unlock(pr->mu);
 }
 
 static void free_port_using_server(char *server, int port) {
@@ -100,31 +101,34 @@
 
   memset(&pr, 0, sizeof(pr));
   memset(&req, 0, sizeof(req));
-  grpc_pollset_init(&pr.pollset);
+
+  pr.pollset = gpr_malloc(grpc_pollset_size());
+  grpc_pollset_init(pr.pollset, &pr.mu);
   grpc_closure_init(&shutdown_closure, destroy_pollset_and_shutdown,
-                    &pr.pollset);
+                    pr.pollset);
 
   req.host = server;
   gpr_asprintf(&path, "/drop/%d", port);
   req.path = path;
 
   grpc_httpcli_context_init(&context);
-  grpc_httpcli_get(&exec_ctx, &context, &pr.pollset, &req,
+  grpc_httpcli_get(&exec_ctx, &context, pr.pollset, &req,
                    GRPC_TIMEOUT_SECONDS_TO_DEADLINE(10), freed_port_from_server,
                    &pr);
-  gpr_mu_lock(GRPC_POLLSET_MU(&pr.pollset));
+  gpr_mu_lock(pr.mu);
   while (!pr.done) {
-    grpc_pollset_worker worker;
-    grpc_pollset_work(&exec_ctx, &pr.pollset, &worker,
+    grpc_pollset_worker *worker = NULL;
+    grpc_pollset_work(&exec_ctx, pr.pollset, &worker,
                       gpr_now(GPR_CLOCK_MONOTONIC),
                       GRPC_TIMEOUT_SECONDS_TO_DEADLINE(1));
   }
-  gpr_mu_unlock(GRPC_POLLSET_MU(&pr.pollset));
+  gpr_mu_unlock(pr.mu);
 
   grpc_httpcli_context_destroy(&context);
   grpc_exec_ctx_finish(&exec_ctx);
-  grpc_pollset_shutdown(&exec_ctx, &pr.pollset, &shutdown_closure);
+  grpc_pollset_shutdown(&exec_ctx, pr.pollset, &shutdown_closure);
   grpc_exec_ctx_finish(&exec_ctx);
+  gpr_free(pr.pollset);
   gpr_free(path);
 }
 
@@ -202,7 +206,8 @@
 }
 
 typedef struct portreq {
-  grpc_pollset pollset;
+  gpr_mu *mu;
+  grpc_pollset *pollset;
   int port;
   int retries;
   char *server;
@@ -234,7 +239,7 @@
     pr->retries++;
     req.host = pr->server;
     req.path = "/get";
-    grpc_httpcli_get(exec_ctx, pr->ctx, &pr->pollset, &req,
+    grpc_httpcli_get(exec_ctx, pr->ctx, pr->pollset, &req,
                      GRPC_TIMEOUT_SECONDS_TO_DEADLINE(10), got_port_from_server,
                      pr);
     return;
@@ -246,10 +251,10 @@
     port = port * 10 + response->body[i] - '0';
   }
   GPR_ASSERT(port > 1024);
-  gpr_mu_lock(GRPC_POLLSET_MU(&pr->pollset));
+  gpr_mu_lock(pr->mu);
   pr->port = port;
-  grpc_pollset_kick(&pr->pollset, NULL);
-  gpr_mu_unlock(GRPC_POLLSET_MU(&pr->pollset));
+  grpc_pollset_kick(pr->pollset, NULL);
+  gpr_mu_unlock(pr->mu);
 }
 
 static int pick_port_using_server(char *server) {
@@ -263,9 +268,10 @@
 
   memset(&pr, 0, sizeof(pr));
   memset(&req, 0, sizeof(req));
-  grpc_pollset_init(&pr.pollset);
+  pr.pollset = gpr_malloc(grpc_pollset_size());
+  grpc_pollset_init(pr.pollset, &pr.mu);
   grpc_closure_init(&shutdown_closure, destroy_pollset_and_shutdown,
-                    &pr.pollset);
+                    pr.pollset);
   pr.port = -1;
   pr.server = server;
   pr.ctx = &context;
@@ -274,22 +280,23 @@
   req.path = "/get";
 
   grpc_httpcli_context_init(&context);
-  grpc_httpcli_get(&exec_ctx, &context, &pr.pollset, &req,
+  grpc_httpcli_get(&exec_ctx, &context, pr.pollset, &req,
                    GRPC_TIMEOUT_SECONDS_TO_DEADLINE(10), got_port_from_server,
                    &pr);
   grpc_exec_ctx_finish(&exec_ctx);
-  gpr_mu_lock(GRPC_POLLSET_MU(&pr.pollset));
+  gpr_mu_lock(pr.mu);
   while (pr.port == -1) {
-    grpc_pollset_worker worker;
-    grpc_pollset_work(&exec_ctx, &pr.pollset, &worker,
+    grpc_pollset_worker *worker = NULL;
+    grpc_pollset_work(&exec_ctx, pr.pollset, &worker,
                       gpr_now(GPR_CLOCK_MONOTONIC),
                       GRPC_TIMEOUT_SECONDS_TO_DEADLINE(1));
   }
-  gpr_mu_unlock(GRPC_POLLSET_MU(&pr.pollset));
+  gpr_mu_unlock(pr.mu);
 
   grpc_httpcli_context_destroy(&context);
-  grpc_pollset_shutdown(&exec_ctx, &pr.pollset, &shutdown_closure);
+  grpc_pollset_shutdown(&exec_ctx, pr.pollset, &shutdown_closure);
   grpc_exec_ctx_finish(&exec_ctx);
+  gpr_free(pr.pollset);
 
   return pr.port;
 }
diff --git a/test/core/util/port_windows.c b/test/core/util/port_windows.c
index 85d7c0c..3b20aeb 100644
--- a/test/core/util/port_windows.c
+++ b/test/core/util/port_windows.c
@@ -129,7 +129,8 @@
 }
 
 typedef struct portreq {
-  grpc_pollset pollset;
+  grpc_pollset *pollset;
+  gpr_mu *mu;
   int port;
 } portreq;
 
@@ -145,10 +146,10 @@
     port = port * 10 + response->body[i] - '0';
   }
   GPR_ASSERT(port > 1024);
-  gpr_mu_lock(GRPC_POLLSET_MU(&pr->pollset));
+  gpr_mu_lock(pr->mu);
   pr->port = port;
-  grpc_pollset_kick(&pr->pollset, NULL);
-  gpr_mu_unlock(GRPC_POLLSET_MU(&pr->pollset));
+  grpc_pollset_kick(pr->pollset, NULL);
+  gpr_mu_unlock(pr->mu);
 }
 
 static void destroy_pollset_and_shutdown(grpc_exec_ctx *exec_ctx, void *p,
@@ -168,32 +169,34 @@
 
   memset(&pr, 0, sizeof(pr));
   memset(&req, 0, sizeof(req));
-  grpc_pollset_init(&pr.pollset);
+  pr.pollset = gpr_malloc(grpc_pollset_size());
+  grpc_pollset_init(pr.pollset, &pr.mu);
   pr.port = -1;
 
   req.host = server;
   req.path = "/get";
 
   grpc_httpcli_context_init(&context);
-  grpc_httpcli_get(&exec_ctx, &context, &pr.pollset, &req,
+  grpc_httpcli_get(&exec_ctx, &context, pr.pollset, &req,
                    GRPC_TIMEOUT_SECONDS_TO_DEADLINE(10), got_port_from_server,
                    &pr);
-  gpr_mu_lock(GRPC_POLLSET_MU(&pr.pollset));
+  gpr_mu_lock(pr.mu);
   while (pr.port == -1) {
-    grpc_pollset_worker worker;
-    grpc_pollset_work(&exec_ctx, &pr.pollset, &worker,
+    grpc_pollset_worker *worker = NULL;
+    grpc_pollset_work(&exec_ctx, pr.pollset, &worker,
                       gpr_now(GPR_CLOCK_MONOTONIC),
                       GRPC_TIMEOUT_SECONDS_TO_DEADLINE(1));
-    gpr_mu_unlock(GRPC_POLLSET_MU(&pr.pollset));
+    gpr_mu_unlock(pr.mu);
     grpc_exec_ctx_flush(&exec_ctx);
-    gpr_mu_lock(GRPC_POLLSET_MU(&pr.pollset));
+    gpr_mu_lock(pr.mu);
   }
-  gpr_mu_unlock(GRPC_POLLSET_MU(&pr.pollset));
+  gpr_mu_unlock(pr.mu);
 
   grpc_httpcli_context_destroy(&context);
   grpc_closure_init(&destroy_pollset_closure, destroy_pollset_and_shutdown,
                     &pr.pollset);
-  grpc_pollset_shutdown(&exec_ctx, &pr.pollset, &destroy_pollset_closure);
+  grpc_pollset_shutdown(&exec_ctx, pr.pollset, &destroy_pollset_closure);
+  gpr_free(pr.pollset);
 
   grpc_exec_ctx_finish(&exec_ctx);
   return pr.port;
diff --git a/test/core/util/test_tcp_server.c b/test/core/util/test_tcp_server.c
index 66470c02..ab37944 100644
--- a/test/core/util/test_tcp_server.c
+++ b/test/core/util/test_tcp_server.c
@@ -57,8 +57,8 @@
   server->tcp_server = NULL;
   grpc_closure_init(&server->shutdown_complete, on_server_destroyed, server);
   server->shutdown = 0;
-  grpc_pollset_init(&server->pollset);
-  server->pollsets[0] = &server->pollset;
+  server->pollset = gpr_malloc(grpc_pollset_size());
+  grpc_pollset_init(server->pollset, &server->mu);
   server->on_connect = on_connect;
   server->cb_data = user_data;
 }
@@ -77,7 +77,7 @@
       grpc_tcp_server_add_port(server->tcp_server, &addr, sizeof(addr));
   GPR_ASSERT(port_added == port);
 
-  grpc_tcp_server_start(&exec_ctx, server->tcp_server, server->pollsets, 1,
+  grpc_tcp_server_start(&exec_ctx, server->tcp_server, &server->pollset, 1,
                         server->on_connect, server->cb_data);
   gpr_log(GPR_INFO, "test tcp server listening on 0.0.0.0:%d", port);
 
@@ -85,15 +85,15 @@
 }
 
 void test_tcp_server_poll(test_tcp_server *server, int seconds) {
-  grpc_pollset_worker worker;
+  grpc_pollset_worker *worker = NULL;
   gpr_timespec deadline =
       gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC),
                    gpr_time_from_seconds(seconds, GPR_TIMESPAN));
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
-  gpr_mu_lock(GRPC_POLLSET_MU(&server->pollset));
-  grpc_pollset_work(&exec_ctx, &server->pollset, &worker,
+  gpr_mu_lock(server->mu);
+  grpc_pollset_work(&exec_ctx, server->pollset, &worker,
                     gpr_now(GPR_CLOCK_MONOTONIC), deadline);
-  gpr_mu_unlock(GRPC_POLLSET_MU(&server->pollset));
+  gpr_mu_unlock(server->mu);
   grpc_exec_ctx_finish(&exec_ctx);
 }
 
@@ -111,8 +111,9 @@
          gpr_time_cmp(gpr_now(GPR_CLOCK_MONOTONIC), shutdown_deadline) < 0) {
     test_tcp_server_poll(server, 1);
   }
-  grpc_pollset_shutdown(&exec_ctx, &server->pollset, &do_nothing_cb);
+  grpc_pollset_shutdown(&exec_ctx, server->pollset, &do_nothing_cb);
   grpc_exec_ctx_finish(&exec_ctx);
-  grpc_pollset_destroy(&server->pollset);
+  grpc_pollset_destroy(server->pollset);
+  gpr_free(server->pollset);
   grpc_shutdown();
 }
diff --git a/test/core/util/test_tcp_server.h b/test/core/util/test_tcp_server.h
index 51119cf..15fcb4f 100644
--- a/test/core/util/test_tcp_server.h
+++ b/test/core/util/test_tcp_server.h
@@ -41,8 +41,8 @@
   grpc_tcp_server *tcp_server;
   grpc_closure shutdown_complete;
   int shutdown;
-  grpc_pollset pollset;
-  grpc_pollset *pollsets[1];
+  gpr_mu *mu;
+  grpc_pollset *pollset;
   grpc_tcp_server_cb on_connect;
   void *cb_data;
 } test_tcp_server;
diff --git a/test/cpp/common/alarm_cpp_test.cc b/test/cpp/common/alarm_cpp_test.cc
index 4745ef1..d4381c0 100644
--- a/test/cpp/common/alarm_cpp_test.cc
+++ b/test/cpp/common/alarm_cpp_test.cc
@@ -55,6 +55,53 @@
   EXPECT_EQ(junk, output_tag);
 }
 
+TEST(AlarmTest, RegularExpiryChrono) {
+  CompletionQueue cq;
+  void* junk = reinterpret_cast<void*>(1618033);
+  std::chrono::system_clock::time_point one_sec_deadline =
+      std::chrono::system_clock::now() + std::chrono::seconds(1);
+  Alarm alarm(&cq, one_sec_deadline, junk);
+
+  void* output_tag;
+  bool ok;
+  const CompletionQueue::NextStatus status = cq.AsyncNext(
+      (void**)&output_tag, &ok, GRPC_TIMEOUT_SECONDS_TO_DEADLINE(2));
+
+  EXPECT_EQ(status, CompletionQueue::GOT_EVENT);
+  EXPECT_TRUE(ok);
+  EXPECT_EQ(junk, output_tag);
+}
+
+TEST(AlarmTest, ZeroExpiry) {
+  CompletionQueue cq;
+  void* junk = reinterpret_cast<void*>(1618033);
+  Alarm alarm(&cq, GRPC_TIMEOUT_SECONDS_TO_DEADLINE(0), junk);
+
+  void* output_tag;
+  bool ok;
+  const CompletionQueue::NextStatus status = cq.AsyncNext(
+      (void**)&output_tag, &ok, GRPC_TIMEOUT_SECONDS_TO_DEADLINE(0));
+
+  EXPECT_EQ(status, CompletionQueue::GOT_EVENT);
+  EXPECT_TRUE(ok);
+  EXPECT_EQ(junk, output_tag);
+}
+
+TEST(AlarmTest, NegativeExpiry) {
+  CompletionQueue cq;
+  void* junk = reinterpret_cast<void*>(1618033);
+  Alarm alarm(&cq, GRPC_TIMEOUT_SECONDS_TO_DEADLINE(-1), junk);
+
+  void* output_tag;
+  bool ok;
+  const CompletionQueue::NextStatus status = cq.AsyncNext(
+      (void**)&output_tag, &ok, GRPC_TIMEOUT_SECONDS_TO_DEADLINE(0));
+
+  EXPECT_EQ(status, CompletionQueue::GOT_EVENT);
+  EXPECT_TRUE(ok);
+  EXPECT_EQ(junk, output_tag);
+}
+
 TEST(AlarmTest, Cancellation) {
   CompletionQueue cq;
   void* junk = reinterpret_cast<void*>(1618033);
diff --git a/test/cpp/end2end/async_end2end_test.cc b/test/cpp/end2end/async_end2end_test.cc
index a194c61..9ca3bf9 100644
--- a/test/cpp/end2end/async_end2end_test.cc
+++ b/test/cpp/end2end/async_end2end_test.cc
@@ -43,6 +43,7 @@
 #include <grpc/grpc.h>
 #include <grpc/support/thd.h>
 #include <grpc/support/time.h>
+#include <grpc/support/tls.h>
 #include <gtest/gtest.h>
 
 #include "src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.h"
@@ -59,6 +60,8 @@
 using grpc::testing::EchoResponse;
 using std::chrono::system_clock;
 
+GPR_TLS_DECL(g_is_async_end2end_test);
+
 namespace grpc {
 namespace testing {
 
@@ -67,9 +70,11 @@
 void* tag(int i) { return (void*)(intptr_t)i; }
 
 #ifdef GPR_POSIX_SOCKET
-static int assert_non_blocking_poll(struct pollfd* pfds, nfds_t nfds,
-                                    int timeout) {
-  GPR_ASSERT(timeout == 0);
+static int maybe_assert_non_blocking_poll(struct pollfd* pfds, nfds_t nfds,
+                                          int timeout) {
+  if (gpr_tls_get(&g_is_async_end2end_test)) {
+    GPR_ASSERT(timeout == 0);
+  }
   return poll(pfds, nfds, timeout);
 }
 
@@ -86,21 +91,21 @@
   grpc_poll_function_type prev_;
 };
 
-class PollingCheckRegion : public PollOverride {
+class PollingOverrider : public PollOverride {
  public:
-  explicit PollingCheckRegion(bool allow_blocking)
-      : PollOverride(allow_blocking ? poll : assert_non_blocking_poll) {}
+  explicit PollingOverrider(bool allow_blocking)
+      : PollOverride(allow_blocking ? poll : maybe_assert_non_blocking_poll) {}
 };
 #else
-class PollingCheckRegion {
+class PollingOverrider {
  public:
-  explicit PollingCheckRegion(bool allow_blocking) {}
+  explicit PollingOverrider(bool allow_blocking) {}
 };
 #endif
 
-class Verifier : public PollingCheckRegion {
+class Verifier {
  public:
-  explicit Verifier(bool spin) : PollingCheckRegion(!spin), spin_(spin) {}
+  explicit Verifier(bool spin) : spin_(spin) {}
   Verifier& Expect(int i, bool expect_ok) {
     expectations_[tag(i)] = expect_ok;
     return *this;
@@ -183,6 +188,8 @@
   AsyncEnd2endTest() {}
 
   void SetUp() GRPC_OVERRIDE {
+    poll_overrider_.reset(new PollingOverrider(!GetParam()));
+
     int port = grpc_pick_unused_port_or_die();
     server_address_ << "localhost:" << port;
 
@@ -193,6 +200,8 @@
     builder.RegisterService(&service_);
     cq_ = builder.AddCompletionQueue();
     server_ = builder.BuildAndStart();
+
+    gpr_tls_set(&g_is_async_end2end_test, 1);
   }
 
   void TearDown() GRPC_OVERRIDE {
@@ -202,6 +211,8 @@
     cq_->Shutdown();
     while (cq_->Next(&ignored_tag, &ignored_ok))
       ;
+    poll_overrider_.reset();
+    gpr_tls_set(&g_is_async_end2end_test, 0);
   }
 
   void ResetStub() {
@@ -249,6 +260,8 @@
   std::unique_ptr<Server> server_;
   grpc::testing::EchoTestService::AsyncService service_;
   std::ostringstream server_address_;
+
+  std::unique_ptr<PollingOverrider> poll_overrider_;
 };
 
 TEST_P(AsyncEnd2endTest, SimpleRpc) {
@@ -976,6 +989,10 @@
 
     if (server_try_cancel == CANCEL_AFTER_PROCESSING) {
       ServerTryCancel(&srv_ctx);
+
+      // Client reads may fail bacause it is notified that the stream is
+      // cancelled.
+      ignore_cq_result = true;
     }
 
     // Client attemts to read the three messages from the server
@@ -1087,7 +1104,7 @@
     Verifier(GetParam()).Expect(7, true).Verify(cq_.get());
 
     // This is expected to fail in all cases i.e for all values of
-    // server_try_cancel. This is becasue at this point, either there are no
+    // server_try_cancel. This is because at this point, either there are no
     // more msgs from the client (because client called WritesDone) or the RPC
     // is cancelled on the server
     srv_stream.Read(&recv_request, tag(8));
@@ -1164,6 +1181,9 @@
 
 int main(int argc, char** argv) {
   grpc_test_init(argc, argv);
+  gpr_tls_init(&g_is_async_end2end_test);
   ::testing::InitGoogleTest(&argc, argv);
-  return RUN_ALL_TESTS();
+  int ret = RUN_ALL_TESTS();
+  gpr_tls_destroy(&g_is_async_end2end_test);
+  return ret;
 }
diff --git a/test/cpp/end2end/end2end_test.cc b/test/cpp/end2end/end2end_test.cc
index c852384..dc2c4f6 100644
--- a/test/cpp/end2end/end2end_test.cc
+++ b/test/cpp/end2end/end2end_test.cc
@@ -51,11 +51,11 @@
 #include "src/core/security/credentials.h"
 #include "src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.h"
 #include "src/proto/grpc/testing/echo.grpc.pb.h"
-#include "test/core/end2end/data/ssl_test_data.h"
 #include "test/core/util/port.h"
 #include "test/core/util/test_config.h"
 #include "test/cpp/end2end/test_service_impl.h"
 #include "test/cpp/util/string_ref_helper.h"
+#include "test/cpp/util/test_credentials_provider.h"
 
 using grpc::testing::EchoRequest;
 using grpc::testing::EchoResponse;
@@ -191,12 +191,14 @@
 
 class TestScenario {
  public:
-  TestScenario(bool proxy, bool tls) : use_proxy(proxy), use_tls(tls) {}
+  TestScenario(bool proxy, const grpc::string& creds_type)
+      : use_proxy(proxy), credentials_type(creds_type) {}
   void Log() const {
-    gpr_log(GPR_INFO, "Scenario: proxy %d, tls %d", use_proxy, use_tls);
+    gpr_log(GPR_INFO, "Scenario: proxy %d, credentials %s", use_proxy,
+            credentials_type.c_str());
   }
   bool use_proxy;
-  bool use_tls;
+  const grpc::string credentials_type;
 };
 
 class End2endTest : public ::testing::TestWithParam<TestScenario> {
@@ -220,14 +222,8 @@
     server_address_ << "127.0.0.1:" << port;
     // Setup server
     ServerBuilder builder;
-    auto server_creds = InsecureServerCredentials();
-    if (GetParam().use_tls) {
-      SslServerCredentialsOptions::PemKeyCertPair pkcp = {test_server1_key,
-                                                          test_server1_cert};
-      SslServerCredentialsOptions ssl_opts;
-      ssl_opts.pem_root_certs = "";
-      ssl_opts.pem_key_cert_pairs.push_back(pkcp);
-      server_creds = SslServerCredentials(ssl_opts);
+    auto server_creds = GetServerCredentials(GetParam().credentials_type);
+    if (GetParam().credentials_type != kInsecureCredentialsType) {
       server_creds->SetAuthMetadataProcessor(processor);
     }
     builder.AddListeningPort(server_address_.str(), server_creds);
@@ -246,12 +242,8 @@
     }
     EXPECT_TRUE(is_server_started_);
     ChannelArguments args;
-    auto channel_creds = InsecureChannelCredentials();
-    if (GetParam().use_tls) {
-      SslCredentialsOptions ssl_opts = {test_root_cert, "", ""};
-      args.SetSslTargetNameOverride("foo.test.google.fr");
-      channel_creds = SslCredentials(ssl_opts);
-    }
+    auto channel_creds =
+        GetChannelCredentials(GetParam().credentials_type, &args);
     if (!user_agent_prefix_.empty()) {
       args.SetUserAgentPrefix(user_agent_prefix_);
     }
@@ -445,9 +437,10 @@
         break;
 
       case CANCEL_AFTER_PROCESSING:
-        // Server cancelled after writing all messages. Client must have read
-        // all messages
-        EXPECT_EQ(num_msgs_read, kNumResponseStreamsMsgs);
+        // Even though the Server cancelled after writing all messages, the RPC
+        // may be cancelled before the Client got a chance to read all the
+        // messages.
+        EXPECT_LE(num_msgs_read, kNumResponseStreamsMsgs);
         break;
 
       default: {
@@ -527,7 +520,11 @@
 
       case CANCEL_AFTER_PROCESSING:
         EXPECT_EQ(num_msgs_sent, num_messages);
-        EXPECT_EQ(num_msgs_read, num_msgs_sent);
+
+        // The Server cancelled after reading the last message and after writing
+        // the message to the client. However, the RPC cancellation might have
+        // taken effect before the client actually read the response.
+        EXPECT_LE(num_msgs_read, num_msgs_sent);
         break;
 
       default:
@@ -912,9 +909,9 @@
   std::thread reader_thread(ReaderThreadFunc, stream.get(), &ev);
   gpr_event_wait(&ev, gpr_inf_future(GPR_CLOCK_REALTIME));
   stream->WritesDone();
+  reader_thread.join();
   Status s = stream->Finish();
   EXPECT_TRUE(s.ok());
-  reader_thread.join();
 }
 
 TEST_P(End2endTest, ChannelState) {
@@ -941,7 +938,7 @@
 
 // Takes 10s.
 TEST_P(End2endTest, ChannelStateTimeout) {
-  if (GetParam().use_tls) {
+  if (GetParam().credentials_type != kInsecureCredentialsType) {
     return;
   }
   int port = grpc_pick_unused_port_or_die();
@@ -1150,7 +1147,7 @@
  protected:
   SecureEnd2endTest() {
     GPR_ASSERT(!GetParam().use_proxy);
-    GPR_ASSERT(GetParam().use_tls);
+    GPR_ASSERT(GetParam().credentials_type != kInsecureCredentialsType);
   }
 };
 
@@ -1373,21 +1370,42 @@
   EXPECT_EQ("*.test.youtube.com", ToString(auth_ctx->GetPeerIdentity()[2]));
 }
 
+std::vector<TestScenario> CreateTestScenarios(bool use_proxy,
+                                              bool test_insecure,
+                                              bool test_secure) {
+  std::vector<TestScenario> scenarios;
+  std::vector<grpc::string> credentials_types;
+  if (test_secure) {
+    credentials_types = GetSecureCredentialsTypeList();
+  }
+  if (test_insecure) {
+    credentials_types.push_back(kInsecureCredentialsType);
+  }
+  for (auto it = credentials_types.begin(); it != credentials_types.end();
+       ++it) {
+    scenarios.push_back(TestScenario(false, *it));
+    if (use_proxy) {
+      scenarios.push_back(TestScenario(true, *it));
+    }
+  }
+  return scenarios;
+}
+
 INSTANTIATE_TEST_CASE_P(End2end, End2endTest,
-                        ::testing::Values(TestScenario(false, false),
-                                          TestScenario(false, true)));
+                        ::testing::ValuesIn(CreateTestScenarios(false, true,
+                                                                true)));
 
 INSTANTIATE_TEST_CASE_P(End2endServerTryCancel, End2endServerTryCancelTest,
-                        ::testing::Values(TestScenario(false, false)));
+                        ::testing::ValuesIn(CreateTestScenarios(false, true,
+                                                                false)));
 
 INSTANTIATE_TEST_CASE_P(ProxyEnd2end, ProxyEnd2endTest,
-                        ::testing::Values(TestScenario(false, false),
-                                          TestScenario(false, true),
-                                          TestScenario(true, false),
-                                          TestScenario(true, true)));
+                        ::testing::ValuesIn(CreateTestScenarios(true, true,
+                                                                true)));
 
 INSTANTIATE_TEST_CASE_P(SecureEnd2end, SecureEnd2endTest,
-                        ::testing::Values(TestScenario(false, true)));
+                        ::testing::ValuesIn(CreateTestScenarios(false, false,
+                                                                true)));
 
 }  // namespace
 }  // namespace testing
diff --git a/test/cpp/end2end/test_service_impl.cc b/test/cpp/end2end/test_service_impl.cc
index 66d11d0..7c3e514 100644
--- a/test/cpp/end2end/test_service_impl.cc
+++ b/test/cpp/end2end/test_service_impl.cc
@@ -326,7 +326,11 @@
   EXPECT_FALSE(context->IsCancelled());
   context->TryCancel();
   gpr_log(GPR_INFO, "Server called TryCancel() to cancel the request");
-  EXPECT_TRUE(context->IsCancelled());
+  // Now wait until it's really canceled
+  while (!context->IsCancelled()) {
+    gpr_sleep_until(gpr_time_add(gpr_now(GPR_CLOCK_REALTIME),
+                                 gpr_time_from_micros(1000, GPR_TIMESPAN)));
+  }
 }
 
 }  // namespace testing
diff --git a/test/cpp/grpclb/grpclb_api_test.cc b/test/cpp/grpclb/grpclb_api_test.cc
new file mode 100644
index 0000000..bd4885f
--- /dev/null
+++ b/test/cpp/grpclb/grpclb_api_test.cc
@@ -0,0 +1,133 @@
+/*
+ *
+ * Copyright 2016, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <gtest/gtest.h>
+#include <string>
+
+#include "src/core/client_config/lb_policies/load_balancer_api.h"
+#include "src/proto/grpc/lb/v0/load_balancer.pb.h"  // C++ version
+
+namespace grpc {
+namespace {
+
+using grpc::lb::v0::LoadBalanceRequest;
+using grpc::lb::v0::LoadBalanceResponse;
+
+class GrpclbTest : public ::testing::Test {};
+
+TEST_F(GrpclbTest, CreateRequest) {
+  const std::string service_name = "AServiceName";
+  LoadBalanceRequest request;
+  grpc_grpclb_request* c_req = grpc_grpclb_request_create(service_name.c_str());
+  gpr_slice slice = grpc_grpclb_request_encode(c_req);
+  const int num_bytes_written = GPR_SLICE_LENGTH(slice);
+  EXPECT_GT(num_bytes_written, 0);
+  request.ParseFromArray(GPR_SLICE_START_PTR(slice), num_bytes_written);
+  EXPECT_EQ(request.initial_request().name(), service_name);
+  gpr_slice_unref(slice);
+  grpc_grpclb_request_destroy(c_req);
+}
+
+TEST_F(GrpclbTest, ParseResponse) {
+  LoadBalanceResponse response;
+  const std::string client_config_str = "I'm a client config";
+  auto* initial_response = response.mutable_initial_response();
+  initial_response->set_client_config(client_config_str);
+  auto* client_stats_report_interval =
+      initial_response->mutable_client_stats_report_interval();
+  client_stats_report_interval->set_seconds(123);
+  client_stats_report_interval->set_nanos(456);
+
+  const std::string encoded_response = response.SerializeAsString();
+  gpr_slice encoded_slice =
+      gpr_slice_from_copied_string(encoded_response.c_str());
+  grpc_grpclb_response* c_response = grpc_grpclb_response_parse(encoded_slice);
+  EXPECT_TRUE(c_response->has_initial_response);
+  EXPECT_TRUE(c_response->initial_response.has_client_config);
+  EXPECT_FALSE(c_response->initial_response.has_load_balancer_delegate);
+  EXPECT_TRUE(strcmp(c_response->initial_response.client_config,
+                     client_config_str.c_str()) == 0);
+  EXPECT_EQ(c_response->initial_response.client_stats_report_interval.seconds,
+            123);
+  EXPECT_EQ(c_response->initial_response.client_stats_report_interval.nanos,
+            456);
+  gpr_slice_unref(encoded_slice);
+  grpc_grpclb_response_destroy(c_response);
+}
+
+TEST_F(GrpclbTest, ParseResponseServerList) {
+  LoadBalanceResponse response;
+  auto* serverlist = response.mutable_server_list();
+  auto* server = serverlist->add_servers();
+  server->set_ip_address("127.0.0.1");
+  server->set_port(12345);
+  server->set_drop_request(true);
+  server = response.mutable_server_list()->add_servers();
+  server->set_ip_address("10.0.0.1");
+  server->set_port(54321);
+  server->set_drop_request(false);
+  auto* expiration_interval = serverlist->mutable_expiration_interval();
+  expiration_interval->set_seconds(888);
+  expiration_interval->set_nanos(999);
+
+  const std::string encoded_response = response.SerializeAsString();
+  gpr_slice encoded_slice =
+      gpr_slice_from_copied_string(encoded_response.c_str());
+  grpc_grpclb_serverlist* c_serverlist =
+      grpc_grpclb_response_parse_serverlist(encoded_slice);
+  ASSERT_EQ(c_serverlist->num_servers, 2ul);
+  EXPECT_TRUE(c_serverlist->servers[0]->has_ip_address);
+  EXPECT_TRUE(strcmp(c_serverlist->servers[0]->ip_address, "127.0.0.1") == 0);
+  EXPECT_EQ(c_serverlist->servers[0]->port, 12345);
+  EXPECT_TRUE(c_serverlist->servers[0]->drop_request);
+  EXPECT_TRUE(c_serverlist->servers[1]->has_ip_address);
+  EXPECT_TRUE(strcmp(c_serverlist->servers[1]->ip_address, "10.0.0.1") == 0);
+  EXPECT_EQ(c_serverlist->servers[1]->port, 54321);
+  EXPECT_FALSE(c_serverlist->servers[1]->drop_request);
+
+  EXPECT_TRUE(c_serverlist->expiration_interval.has_seconds);
+  EXPECT_EQ(c_serverlist->expiration_interval.seconds, 888);
+  EXPECT_TRUE(c_serverlist->expiration_interval.has_nanos);
+  EXPECT_EQ(c_serverlist->expiration_interval.nanos, 999);
+
+  gpr_slice_unref(encoded_slice);
+  grpc_grpclb_destroy_serverlist(c_serverlist);
+}
+
+}  // namespace
+}  // namespace grpc
+
+int main(int argc, char** argv) {
+  ::testing::InitGoogleTest(&argc, argv);
+  return RUN_ALL_TESTS();
+}
diff --git a/test/cpp/interop/client.cc b/test/cpp/interop/client.cc
index cb9b396..788adef 100644
--- a/test/cpp/interop/client.cc
+++ b/test/cpp/interop/client.cc
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -74,6 +74,7 @@
               "oauth2_auth_token: raw oauth2 access token auth; "
               "per_rpc_creds: raw oauth2 access token on a single rpc; "
               "status_code_and_message: verify status code & message; "
+              "custom_metadata: server will echo custom metadata;"
               "all : all of above.");
 DEFINE_string(default_service_account, "",
               "Email of GCE default service account");
@@ -129,6 +130,8 @@
     client.DoPerRpcCreds(json_key);
   } else if (FLAGS_test_case == "status_code_and_message") {
     client.DoStatusWithMessage();
+  } else if (FLAGS_test_case == "custom_metadata") {
+    client.DoCustomMetadata();
   } else if (FLAGS_test_case == "all") {
     client.DoEmpty();
     client.DoLargeUnary();
@@ -142,6 +145,7 @@
     client.DoTimeoutOnSleepingServer();
     client.DoEmptyStream();
     client.DoStatusWithMessage();
+    client.DoCustomMetadata();
     // service_account_creds and jwt_token_creds can only run with ssl.
     if (FLAGS_use_tls) {
       grpc::string json_key = GetServiceAccountJsonKey();
@@ -159,7 +163,7 @@
         "server_compressed_streaming|half_duplex|ping_pong|cancel_after_begin|"
         "cancel_after_first_response|timeout_on_sleeping_server|empty_stream|"
         "compute_engine_creds|jwt_token_creds|oauth2_auth_token|per_rpc_creds",
-        FLAGS_test_case.c_str());
+        "status_code_and_message|custom_metadata", FLAGS_test_case.c_str());
     ret = 1;
   }
 
diff --git a/test/cpp/interop/interop_client.cc b/test/cpp/interop/interop_client.cc
index b063107..46f6fda 100644
--- a/test/cpp/interop/interop_client.cc
+++ b/test/cpp/interop/interop_client.cc
@@ -625,5 +625,77 @@
   gpr_log(GPR_DEBUG, "Done testing Status and Message");
 }
 
+void InteropClient::DoCustomMetadata() {
+  const grpc::string kEchoInitialMetadataKey("x-grpc-test-echo-initial");
+  const grpc::string kInitialMetadataValue("test_initial_metadata_value");
+  const grpc::string kEchoTrailingBinMetadataKey(
+      "x-grpc-test-echo-trailing-bin");
+  const grpc::string kTrailingBinValue("\x0a\x0b\x0a\x0b\x0a\x0b");
+  ;
+
+  {
+    gpr_log(GPR_DEBUG, "Sending RPC with custom metadata");
+    ClientContext context;
+    context.AddMetadata(kEchoInitialMetadataKey, kInitialMetadataValue);
+    context.AddMetadata(kEchoTrailingBinMetadataKey, kTrailingBinValue);
+    SimpleRequest request;
+    SimpleResponse response;
+    request.set_response_size(kLargeResponseSize);
+    grpc::string payload(kLargeRequestSize, '\0');
+    request.mutable_payload()->set_body(payload.c_str(), kLargeRequestSize);
+
+    Status s = serviceStub_.Get()->UnaryCall(&context, request, &response);
+    AssertOkOrPrintErrorStatus(s);
+    const auto& server_initial_metadata = context.GetServerInitialMetadata();
+    auto iter = server_initial_metadata.find(kEchoInitialMetadataKey);
+    GPR_ASSERT(iter != server_initial_metadata.end());
+    GPR_ASSERT(iter->second.data() == kInitialMetadataValue);
+    const auto& server_trailing_metadata = context.GetServerTrailingMetadata();
+    iter = server_trailing_metadata.find(kEchoTrailingBinMetadataKey);
+    GPR_ASSERT(iter != server_trailing_metadata.end());
+    GPR_ASSERT(grpc::string(iter->second.begin(), iter->second.end()) ==
+               kTrailingBinValue);
+
+    gpr_log(GPR_DEBUG, "Done testing RPC with custom metadata");
+  }
+
+  {
+    gpr_log(GPR_DEBUG, "Sending stream with custom metadata");
+    ClientContext context;
+    context.AddMetadata(kEchoInitialMetadataKey, kInitialMetadataValue);
+    context.AddMetadata(kEchoTrailingBinMetadataKey, kTrailingBinValue);
+    std::unique_ptr<ClientReaderWriter<StreamingOutputCallRequest,
+                                       StreamingOutputCallResponse>>
+        stream(serviceStub_.Get()->FullDuplexCall(&context));
+
+    StreamingOutputCallRequest request;
+    request.set_response_type(PayloadType::COMPRESSABLE);
+    ResponseParameters* response_parameter = request.add_response_parameters();
+    response_parameter->set_size(kLargeResponseSize);
+    grpc::string payload(kLargeRequestSize, '\0');
+    request.mutable_payload()->set_body(payload.c_str(), kLargeRequestSize);
+    StreamingOutputCallResponse response;
+    GPR_ASSERT(stream->Write(request));
+    stream->WritesDone();
+    GPR_ASSERT(stream->Read(&response));
+    GPR_ASSERT(response.payload().body() ==
+               grpc::string(kLargeResponseSize, '\0'));
+    GPR_ASSERT(!stream->Read(&response));
+    Status s = stream->Finish();
+    AssertOkOrPrintErrorStatus(s);
+    const auto& server_initial_metadata = context.GetServerInitialMetadata();
+    auto iter = server_initial_metadata.find(kEchoInitialMetadataKey);
+    GPR_ASSERT(iter != server_initial_metadata.end());
+    GPR_ASSERT(iter->second.data() == kInitialMetadataValue);
+    const auto& server_trailing_metadata = context.GetServerTrailingMetadata();
+    iter = server_trailing_metadata.find(kEchoTrailingBinMetadataKey);
+    GPR_ASSERT(iter != server_trailing_metadata.end());
+    GPR_ASSERT(grpc::string(iter->second.begin(), iter->second.end()) ==
+               kTrailingBinValue);
+
+    gpr_log(GPR_DEBUG, "Done testing stream with custom metadata");
+  }
+}
+
 }  // namespace testing
 }  // namespace grpc
diff --git a/test/cpp/interop/interop_client.h b/test/cpp/interop/interop_client.h
index 3ecd380..3f57f3c 100644
--- a/test/cpp/interop/interop_client.h
+++ b/test/cpp/interop/interop_client.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -75,6 +75,7 @@
   void DoTimeoutOnSleepingServer();
   void DoEmptyStream();
   void DoStatusWithMessage();
+  void DoCustomMetadata();
   // Auth tests.
   // username is a string containing the user email
   void DoJwtTokenCreds(const grpc::string& username);
diff --git a/test/cpp/interop/metrics_client.cc b/test/cpp/interop/metrics_client.cc
index 0c140ff..bd48c7d 100644
--- a/test/cpp/interop/metrics_client.cc
+++ b/test/cpp/interop/metrics_client.cc
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -37,39 +37,45 @@
 #include <gflags/gflags.h>
 #include <grpc++/grpc++.h>
 
-#include "test/cpp/util/metrics_server.h"
-#include "test/cpp/util/test_config.h"
 #include "src/proto/grpc/testing/metrics.grpc.pb.h"
 #include "src/proto/grpc/testing/metrics.pb.h"
+#include "test/cpp/util/metrics_server.h"
+#include "test/cpp/util/test_config.h"
 
 DEFINE_string(metrics_server_address, "",
               "The metrics server addresses in the fomrat <hostname>:<port>");
+DEFINE_bool(total_only, false,
+            "If true, this prints only the total value of all gauges");
+
+int kDeadlineSecs = 10;
 
 using grpc::testing::EmptyMessage;
 using grpc::testing::GaugeResponse;
 using grpc::testing::MetricsService;
 using grpc::testing::MetricsServiceImpl;
 
-void PrintMetrics(const grpc::string& server_address) {
-  gpr_log(GPR_INFO, "creating a channel to %s", server_address.c_str());
-  std::shared_ptr<grpc::Channel> channel(
-      grpc::CreateChannel(server_address, grpc::InsecureChannelCredentials()));
-
-  std::unique_ptr<MetricsService::Stub> stub(MetricsService::NewStub(channel));
-
+// Prints the values of all Gauges (unless total_only is set to 'true' in which
+// case this only prints the sum of all gauge values).
+bool PrintMetrics(std::unique_ptr<MetricsService::Stub> stub, bool total_only) {
   grpc::ClientContext context;
   EmptyMessage message;
 
+  std::chrono::system_clock::time_point deadline =
+      std::chrono::system_clock::now() + std::chrono::seconds(kDeadlineSecs);
+
+  context.set_deadline(deadline);
+
   std::unique_ptr<grpc::ClientReader<GaugeResponse>> reader(
       stub->GetAllGauges(&context, message));
 
   GaugeResponse gauge_response;
   long overall_qps = 0;
-  int idx = 0;
   while (reader->Read(&gauge_response)) {
     if (gauge_response.value_case() == GaugeResponse::kLongValue) {
-      gpr_log(GPR_INFO, "Gauge: %d (%s: %ld)", ++idx,
-              gauge_response.name().c_str(), gauge_response.long_value());
+      if (!total_only) {
+        gpr_log(GPR_INFO, "%s: %ld", gauge_response.name().c_str(),
+                gauge_response.long_value());
+      }
       overall_qps += gauge_response.long_value();
     } else {
       gpr_log(GPR_INFO, "Gauge %s is not a long value",
@@ -77,12 +83,14 @@
     }
   }
 
-  gpr_log(GPR_INFO, "OVERALL: %ld", overall_qps);
+  gpr_log(GPR_INFO, "%ld", overall_qps);
 
   const grpc::Status status = reader->Finish();
   if (!status.ok()) {
     gpr_log(GPR_ERROR, "Error in getting metrics from the client");
   }
+
+  return status.ok();
 }
 
 int main(int argc, char** argv) {
@@ -97,7 +105,12 @@
     return 1;
   }
 
-  PrintMetrics(FLAGS_metrics_server_address);
+  std::shared_ptr<grpc::Channel> channel(grpc::CreateChannel(
+      FLAGS_metrics_server_address, grpc::InsecureChannelCredentials()));
+
+  if (!PrintMetrics(MetricsService::NewStub(channel), FLAGS_total_only)) {
+    return 1;
+  }
 
   return 0;
 }
diff --git a/test/cpp/interop/reconnect_interop_client.cc b/test/cpp/interop/reconnect_interop_client.cc
index 1f6b352..79a60cc 100644
--- a/test/cpp/interop/reconnect_interop_client.cc
+++ b/test/cpp/interop/reconnect_interop_client.cc
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/test/cpp/interop/reconnect_interop_server.cc b/test/cpp/interop/reconnect_interop_server.cc
index 3602b8c..41cff43 100644
--- a/test/cpp/interop/reconnect_interop_server.cc
+++ b/test/cpp/interop/reconnect_interop_server.cc
@@ -31,6 +31,8 @@
  *
  */
 
+// Test description at doc/connection-backoff-interop-test-description.md
+
 #include <signal.h>
 #include <unistd.h>
 
diff --git a/test/cpp/interop/server.cc b/test/cpp/interop/server_main.cc
similarity index 86%
rename from test/cpp/interop/server.cc
rename to test/cpp/interop/server_main.cc
index cdca060..18ac35d 100644
--- a/test/cpp/interop/server.cc
+++ b/test/cpp/interop/server_main.cc
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -80,6 +80,36 @@
 static bool got_sigint = false;
 static const char* kRandomFile = "test/cpp/interop/rnd.dat";
 
+const char kEchoInitialMetadataKey[] = "x-grpc-test-echo-initial";
+const char kEchoTrailingBinMetadataKey[] = "x-grpc-test-echo-trailing-bin";
+const char kEchoUserAgentKey[] = "x-grpc-test-echo-useragent";
+
+void MaybeEchoMetadata(ServerContext* context) {
+  const auto& client_metadata = context->client_metadata();
+  GPR_ASSERT(client_metadata.count(kEchoInitialMetadataKey) <= 1);
+  GPR_ASSERT(client_metadata.count(kEchoTrailingBinMetadataKey) <= 1);
+
+  auto iter = client_metadata.find(kEchoInitialMetadataKey);
+  if (iter != client_metadata.end()) {
+    context->AddInitialMetadata(kEchoInitialMetadataKey, iter->second.data());
+  }
+  iter = client_metadata.find(kEchoTrailingBinMetadataKey);
+  if (iter != client_metadata.end()) {
+    context->AddTrailingMetadata(
+        kEchoTrailingBinMetadataKey,
+        grpc::string(iter->second.begin(), iter->second.end()));
+  }
+  // Check if client sent a magic key in the header that makes us echo
+  // back the user-agent (for testing purpose)
+  iter = client_metadata.find(kEchoUserAgentKey);
+  if (iter != client_metadata.end()) {
+    iter = client_metadata.find("user-agent");
+    if (iter != client_metadata.end()) {
+      context->AddInitialMetadata(kEchoUserAgentKey, iter->second.data());
+    }
+  }
+}
+
 bool SetPayload(PayloadType type, int size, Payload* payload) {
   PayloadType response_type;
   if (type == PayloadType::RANDOM) {
@@ -130,11 +160,13 @@
  public:
   Status EmptyCall(ServerContext* context, const grpc::testing::Empty* request,
                    grpc::testing::Empty* response) {
+    MaybeEchoMetadata(context);
     return Status::OK;
   }
 
   Status UnaryCall(ServerContext* context, const SimpleRequest* request,
                    SimpleResponse* response) {
+    MaybeEchoMetadata(context);
     SetResponseCompression(context, *request);
     if (request->response_size() > 0) {
       if (!SetPayload(request->response_type(), request->response_size(),
@@ -192,6 +224,7 @@
       ServerContext* context,
       ServerReaderWriter<StreamingOutputCallResponse,
                          StreamingOutputCallRequest>* stream) {
+    MaybeEchoMetadata(context);
     StreamingOutputCallRequest request;
     StreamingOutputCallResponse response;
     bool write_success = true;
diff --git a/test/cpp/qps/client.h b/test/cpp/qps/client.h
index c94a523..2dc83f0 100644
--- a/test/cpp/qps/client.h
+++ b/test/cpp/qps/client.h
@@ -46,10 +46,10 @@
 #include "src/proto/grpc/testing/payloads.grpc.pb.h"
 #include "src/proto/grpc/testing/services.grpc.pb.h"
 
-#include "test/cpp/qps/limit_cores.h"
 #include "test/cpp/qps/histogram.h"
 #include "test/cpp/qps/interarrival.h"
-#include "test/cpp/qps/timer.h"
+#include "test/cpp/qps/limit_cores.h"
+#include "test/cpp/qps/usage_timer.h"
 #include "test/cpp/util/create_test_channel.h"
 
 namespace grpc {
@@ -112,12 +112,12 @@
 
 class Client {
  public:
-  Client() : timer_(new Timer), interarrival_timer_() {}
+  Client() : timer_(new UsageTimer), interarrival_timer_() {}
   virtual ~Client() {}
 
   ClientStats Mark(bool reset) {
     Histogram latencies;
-    Timer::Result timer_result;
+    UsageTimer::Result timer_result;
 
     // avoid std::vector for old compilers that expect a copy constructor
     if (reset) {
@@ -125,7 +125,7 @@
       for (size_t i = 0; i < threads_.size(); i++) {
         threads_[i]->BeginSwap(&to_merge[i]);
       }
-      std::unique_ptr<Timer> timer(new Timer);
+      std::unique_ptr<UsageTimer> timer(new UsageTimer);
       timer_.swap(timer);
       for (size_t i = 0; i < threads_.size(); i++) {
         threads_[i]->EndSwap();
@@ -294,7 +294,7 @@
   };
 
   std::vector<std::unique_ptr<Thread>> threads_;
-  std::unique_ptr<Timer> timer_;
+  std::unique_ptr<UsageTimer> timer_;
 
   InterarrivalTimer interarrival_timer_;
   std::vector<gpr_timespec> next_time_;
diff --git a/test/cpp/qps/client_async.cc b/test/cpp/qps/client_async.cc
index 9e8767d..9e9da99 100644
--- a/test/cpp/qps/client_async.cc
+++ b/test/cpp/qps/client_async.cc
@@ -54,7 +54,7 @@
 
 #include "src/proto/grpc/testing/services.grpc.pb.h"
 #include "test/cpp/qps/client.h"
-#include "test/cpp/qps/timer.h"
+#include "test/cpp/qps/usage_timer.h"
 #include "test/cpp/util/create_test_channel.h"
 
 namespace grpc {
@@ -107,14 +107,14 @@
   bool RunNextState(bool ok, Histogram* hist) GRPC_OVERRIDE {
     switch (next_state_) {
       case State::READY:
-        start_ = Timer::Now();
+        start_ = UsageTimer::Now();
         response_reader_ = start_req_(stub_, &context_, req_, cq_);
         response_reader_->Finish(&response_, &status_,
                                  ClientRpcContext::tag(this));
         next_state_ = State::RESP_DONE;
         return true;
       case State::RESP_DONE:
-        hist->Add((Timer::Now() - start_) * 1e9);
+        hist->Add((UsageTimer::Now() - start_) * 1e9);
         callback_(status_, &response_);
         next_state_ = State::INVALID;
         return false;
@@ -287,8 +287,7 @@
         next_state_(State::INVALID),
         callback_(on_done),
         next_issue_(next_issue),
-        start_req_(start_req),
-        start_(Timer::Now()) {}
+        start_req_(start_req) {}
   ~ClientRpcContextStreamingImpl() GRPC_OVERRIDE {}
   void Start(CompletionQueue* cq) GRPC_OVERRIDE {
     cq_ = cq;
@@ -314,7 +313,7 @@
           if (!ok) {
             return false;
           }
-          start_ = Timer::Now();
+          start_ = UsageTimer::Now();
           next_state_ = State::WRITE_DONE;
           stream_->Write(req_, ClientRpcContext::tag(this));
           return true;
@@ -327,7 +326,7 @@
           return true;
           break;
         case State::READ_DONE:
-          hist->Add((Timer::Now() - start_) * 1e9);
+          hist->Add((UsageTimer::Now() - start_) * 1e9);
           callback_(status_, &response_);
           next_state_ = State::STREAM_IDLE;
           break;  // loop around
@@ -415,8 +414,7 @@
         next_state_(State::INVALID),
         callback_(on_done),
         next_issue_(next_issue),
-        start_req_(start_req),
-        start_(Timer::Now()) {}
+        start_req_(start_req) {}
   ~ClientRpcContextGenericStreamingImpl() GRPC_OVERRIDE {}
   void Start(CompletionQueue* cq) GRPC_OVERRIDE {
     cq_ = cq;
@@ -445,7 +443,7 @@
           if (!ok) {
             return false;
           }
-          start_ = Timer::Now();
+          start_ = UsageTimer::Now();
           next_state_ = State::WRITE_DONE;
           stream_->Write(req_, ClientRpcContext::tag(this));
           return true;
@@ -458,7 +456,7 @@
           return true;
           break;
         case State::READ_DONE:
-          hist->Add((Timer::Now() - start_) * 1e9);
+          hist->Add((UsageTimer::Now() - start_) * 1e9);
           callback_(status_, &response_);
           next_state_ = State::STREAM_IDLE;
           break;  // loop around
diff --git a/test/cpp/qps/client_sync.cc b/test/cpp/qps/client_sync.cc
index edfc246..4284e07 100644
--- a/test/cpp/qps/client_sync.cc
+++ b/test/cpp/qps/client_sync.cc
@@ -58,7 +58,7 @@
 #include "test/cpp/qps/client.h"
 #include "test/cpp/qps/histogram.h"
 #include "test/cpp/qps/interarrival.h"
-#include "test/cpp/qps/timer.h"
+#include "test/cpp/qps/usage_timer.h"
 
 namespace grpc {
 namespace testing {
@@ -104,12 +104,12 @@
   bool ThreadFunc(Histogram* histogram, size_t thread_idx) GRPC_OVERRIDE {
     WaitToIssue(thread_idx);
     auto* stub = channels_[thread_idx % channels_.size()].get_stub();
-    double start = Timer::Now();
+    double start = UsageTimer::Now();
     GPR_TIMER_SCOPE("SynchronousUnaryClient::ThreadFunc", 0);
     grpc::ClientContext context;
     grpc::Status s =
         stub->UnaryCall(&context, request_, &responses_[thread_idx]);
-    histogram->Add((Timer::Now() - start) * 1e9);
+    histogram->Add((UsageTimer::Now() - start) * 1e9);
     return s.ok();
   }
 };
@@ -143,10 +143,10 @@
   bool ThreadFunc(Histogram* histogram, size_t thread_idx) GRPC_OVERRIDE {
     WaitToIssue(thread_idx);
     GPR_TIMER_SCOPE("SynchronousStreamingClient::ThreadFunc", 0);
-    double start = Timer::Now();
+    double start = UsageTimer::Now();
     if (stream_[thread_idx]->Write(request_) &&
         stream_[thread_idx]->Read(&responses_[thread_idx])) {
-      histogram->Add((Timer::Now() - start) * 1e9);
+      histogram->Add((UsageTimer::Now() - start) * 1e9);
       return true;
     }
     return false;
diff --git a/test/cpp/qps/qps-sweep.sh b/test/cpp/qps/qps-sweep.sh
index 7a35788..9d3f053 100755
--- a/test/cpp/qps/qps-sweep.sh
+++ b/test/cpp/qps/qps-sweep.sh
@@ -72,7 +72,7 @@
     --server_type=ASYNC_GENERIC_SERVER --outstanding_rpcs_per_channel=$deep \
     --client_channels=$wide --bbuf_req_size=0 --bbuf_resp_size=0 \
     --async_client_threads=0 --async_server_threads=0 --secure_test=$secure \
-    --num_servers=1 --num_clients=0 |& tee /tmp/qps-test.$$
+    --num_servers=1 --num_clients=0 2>&1 | tee /tmp/qps-test.$$
 
   # Scenario 2b: QPS with a single server core
   "$bins"/opt/qps_driver --rpc_type=STREAMING --client_type=ASYNC_CLIENT \
diff --git a/test/cpp/qps/qps_openloop_test.cc b/test/cpp/qps/qps_openloop_test.cc
index 0ac41d9..27f266b 100644
--- a/test/cpp/qps/qps_openloop_test.cc
+++ b/test/cpp/qps/qps_openloop_test.cc
@@ -35,6 +35,7 @@
 
 #include <grpc/support/log.h>
 
+#include "test/core/util/test_config.h"
 #include "test/cpp/qps/driver.h"
 #include "test/cpp/qps/report.h"
 #include "test/cpp/util/benchmark_config.h"
@@ -55,11 +56,11 @@
   client_config.set_async_client_threads(8);
   client_config.set_rpc_type(STREAMING);
   client_config.mutable_load_params()->mutable_poisson()->set_offered_load(
-      1000.0);
+      1000.0 / GRPC_TEST_SLOWDOWN_FACTOR);
 
   ServerConfig server_config;
   server_config.set_server_type(ASYNC_SERVER);
-  server_config.set_async_server_threads(4);
+  server_config.set_async_server_threads(8);
 
   const auto result =
       RunScenario(client_config, 1, server_config, 1, WARMUP, BENCHMARK, -2);
diff --git a/test/cpp/qps/server.h b/test/cpp/qps/server.h
index 94a6f8a..de46452 100644
--- a/test/cpp/qps/server.h
+++ b/test/cpp/qps/server.h
@@ -43,14 +43,14 @@
 #include "test/core/end2end/data/ssl_test_data.h"
 #include "test/core/util/port.h"
 #include "test/cpp/qps/limit_cores.h"
-#include "test/cpp/qps/timer.h"
+#include "test/cpp/qps/usage_timer.h"
 
 namespace grpc {
 namespace testing {
 
 class Server {
  public:
-  explicit Server(const ServerConfig& config) : timer_(new Timer) {
+  explicit Server(const ServerConfig& config) : timer_(new UsageTimer) {
     cores_ = LimitCores(config.core_list().data(), config.core_list_size());
     if (config.port()) {
       port_ = config.port();
@@ -62,9 +62,9 @@
   virtual ~Server() {}
 
   ServerStats Mark(bool reset) {
-    Timer::Result timer_result;
+    UsageTimer::Result timer_result;
     if (reset) {
-      std::unique_ptr<Timer> timer(new Timer);
+      std::unique_ptr<UsageTimer> timer(new UsageTimer);
       timer.swap(timer_);
       timer_result = timer->Mark();
     } else {
@@ -108,7 +108,7 @@
  private:
   int port_;
   int cores_;
-  std::unique_ptr<Timer> timer_;
+  std::unique_ptr<UsageTimer> timer_;
 };
 
 std::unique_ptr<Server> CreateSynchronousServer(const ServerConfig& config);
diff --git a/test/cpp/qps/server_sync.cc b/test/cpp/qps/server_sync.cc
index 4b77882..b7682f5 100644
--- a/test/cpp/qps/server_sync.cc
+++ b/test/cpp/qps/server_sync.cc
@@ -34,18 +34,18 @@
 #include <thread>
 
 #include <gflags/gflags.h>
+#include <grpc++/security/server_credentials.h>
+#include <grpc++/server.h>
+#include <grpc++/server_builder.h>
+#include <grpc++/server_context.h>
 #include <grpc/grpc.h>
 #include <grpc/support/alloc.h>
 #include <grpc/support/host_port.h>
 #include <grpc/support/log.h>
-#include <grpc++/server.h>
-#include <grpc++/server_builder.h>
-#include <grpc++/server_context.h>
-#include <grpc++/security/server_credentials.h>
 
-#include "test/cpp/qps/server.h"
-#include "test/cpp/qps/timer.h"
 #include "src/proto/grpc/testing/services.grpc.pb.h"
+#include "test/cpp/qps/server.h"
+#include "test/cpp/qps/usage_timer.h"
 
 namespace grpc {
 namespace testing {
diff --git a/test/cpp/qps/timer.cc b/test/cpp/qps/usage_timer.cc
similarity index 90%
rename from test/cpp/qps/timer.cc
rename to test/cpp/qps/usage_timer.cc
index 3ec7f49..6663a9a 100644
--- a/test/cpp/qps/timer.cc
+++ b/test/cpp/qps/usage_timer.cc
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,15 +31,15 @@
  *
  */
 
-#include "test/cpp/qps/timer.h"
+#include "test/cpp/qps/usage_timer.h"
 
-#include <sys/time.h>
-#include <sys/resource.h>
 #include <grpc/support/time.h>
+#include <sys/resource.h>
+#include <sys/time.h>
 
-Timer::Timer() : start_(Sample()) {}
+UsageTimer::UsageTimer() : start_(Sample()) {}
 
-double Timer::Now() {
+double UsageTimer::Now() {
   auto ts = gpr_now(GPR_CLOCK_REALTIME);
   return ts.tv_sec + 1e-9 * ts.tv_nsec;
 }
@@ -48,7 +48,7 @@
   return tv->tv_sec + 1e-6 * tv->tv_usec;
 }
 
-Timer::Result Timer::Sample() {
+UsageTimer::Result UsageTimer::Sample() {
   struct rusage usage;
   struct timeval tv;
   gettimeofday(&tv, NULL);
@@ -61,7 +61,7 @@
   return r;
 }
 
-Timer::Result Timer::Mark() const {
+UsageTimer::Result UsageTimer::Mark() const {
   Result s = Sample();
   Result r;
   r.wall = s.wall - start_.wall;
diff --git a/test/cpp/qps/timer.h b/test/cpp/qps/usage_timer.h
similarity index 92%
rename from test/cpp/qps/timer.h
rename to test/cpp/qps/usage_timer.h
index d1aee1a..d19f820 100644
--- a/test/cpp/qps/timer.h
+++ b/test/cpp/qps/usage_timer.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,12 +31,12 @@
  *
  */
 
-#ifndef TEST_QPS_TIMER_H
-#define TEST_QPS_TIMER_H
+#ifndef TEST_QPS_USAGE_TIMER_H
+#define TEST_QPS_USAGE_TIMER_H
 
-class Timer {
+class UsageTimer {
  public:
-  Timer();
+  UsageTimer();
 
   struct Result {
     double wall;
diff --git a/test/cpp/util/metrics_server.cc b/test/cpp/util/metrics_server.cc
index 07978d0..34d51eb 100644
--- a/test/cpp/util/metrics_server.cc
+++ b/test/cpp/util/metrics_server.cc
@@ -57,7 +57,7 @@
 grpc::Status MetricsServiceImpl::GetAllGauges(
     ServerContext* context, const EmptyMessage* request,
     ServerWriter<GaugeResponse>* writer) {
-  gpr_log(GPR_INFO, "GetAllGauges called");
+  gpr_log(GPR_DEBUG, "GetAllGauges called");
 
   std::lock_guard<std::mutex> lock(mu_);
   for (auto it = gauges_.begin(); it != gauges_.end(); it++) {
diff --git a/test/cpp/util/test_credentials_provider.cc b/test/cpp/util/test_credentials_provider.cc
new file mode 100644
index 0000000..e314fd6
--- /dev/null
+++ b/test/cpp/util/test_credentials_provider.cc
@@ -0,0 +1,174 @@
+
+/*
+ *
+ * Copyright 2016, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "test/cpp/util/test_credentials_provider.h"
+
+#include <unordered_map>
+
+#include <grpc/support/sync.h>
+#include <grpc++/impl/sync.h>
+
+#include "test/core/end2end/data/ssl_test_data.h"
+
+namespace {
+
+using grpc::ChannelArguments;
+using grpc::ChannelCredentials;
+using grpc::InsecureChannelCredentials;
+using grpc::InsecureServerCredentials;
+using grpc::ServerCredentials;
+using grpc::SslCredentialsOptions;
+using grpc::SslServerCredentialsOptions;
+using grpc::testing::CredentialTypeProvider;
+
+// Provide test credentials. Thread-safe.
+class CredentialsProvider {
+ public:
+  virtual ~CredentialsProvider() {}
+
+  virtual void AddSecureType(
+      const grpc::string& type,
+      std::unique_ptr<CredentialTypeProvider> type_provider) = 0;
+  virtual std::shared_ptr<ChannelCredentials> GetChannelCredentials(
+      const grpc::string& type, ChannelArguments* args) = 0;
+  virtual std::shared_ptr<ServerCredentials> GetServerCredentials(
+      const grpc::string& type) = 0;
+  virtual std::vector<grpc::string> GetSecureCredentialsTypeList() = 0;
+};
+
+class DefaultCredentialsProvider : public CredentialsProvider {
+ public:
+  ~DefaultCredentialsProvider() override {}
+
+  void AddSecureType(
+      const grpc::string& type,
+      std::unique_ptr<CredentialTypeProvider> type_provider) override {
+    // This clobbers any existing entry for type, except the defaults, which
+    // can't be clobbered.
+    grpc::unique_lock<grpc::mutex> lock(mu_);
+    added_secure_types_[type] = std::move(type_provider);
+  }
+
+  std::shared_ptr<ChannelCredentials> GetChannelCredentials(
+      const grpc::string& type, ChannelArguments* args) override {
+    if (type == grpc::testing::kInsecureCredentialsType) {
+      return InsecureChannelCredentials();
+    } else if (type == grpc::testing::kTlsCredentialsType) {
+      SslCredentialsOptions ssl_opts = {test_root_cert, "", ""};
+      args->SetSslTargetNameOverride("foo.test.google.fr");
+      return SslCredentials(ssl_opts);
+    } else {
+      grpc::unique_lock<grpc::mutex> lock(mu_);
+      auto it(added_secure_types_.find(type));
+      if (it == added_secure_types_.end()) {
+        gpr_log(GPR_ERROR, "Unsupported credentials type %s.", type.c_str());
+        return nullptr;
+      }
+      return it->second->GetChannelCredentials(args);
+    }
+  }
+
+  std::shared_ptr<ServerCredentials> GetServerCredentials(
+      const grpc::string& type) override {
+    if (type == grpc::testing::kInsecureCredentialsType) {
+      return InsecureServerCredentials();
+    } else if (type == grpc::testing::kTlsCredentialsType) {
+      SslServerCredentialsOptions::PemKeyCertPair pkcp = {test_server1_key,
+                                                          test_server1_cert};
+      SslServerCredentialsOptions ssl_opts;
+      ssl_opts.pem_root_certs = "";
+      ssl_opts.pem_key_cert_pairs.push_back(pkcp);
+      return SslServerCredentials(ssl_opts);
+    } else {
+      grpc::unique_lock<grpc::mutex> lock(mu_);
+      auto it(added_secure_types_.find(type));
+      if (it == added_secure_types_.end()) {
+        gpr_log(GPR_ERROR, "Unsupported credentials type %s.", type.c_str());
+        return nullptr;
+      }
+      return it->second->GetServerCredentials();
+    }
+  }
+  std::vector<grpc::string> GetSecureCredentialsTypeList() override {
+    std::vector<grpc::string> types;
+    types.push_back(grpc::testing::kTlsCredentialsType);
+    grpc::unique_lock<grpc::mutex> lock(mu_);
+    for (const auto& type_pair : added_secure_types_) {
+      types.push_back(type_pair.first);
+    }
+    return types;
+  }
+
+ private:
+  grpc::mutex mu_;
+  std::unordered_map<grpc::string, std::unique_ptr<CredentialTypeProvider> >
+      added_secure_types_;
+};
+
+gpr_once g_once_init_provider = GPR_ONCE_INIT;
+CredentialsProvider* g_provider = nullptr;
+
+void CreateDefaultProvider() { g_provider = new DefaultCredentialsProvider; }
+
+CredentialsProvider* GetProvider() {
+  gpr_once_init(&g_once_init_provider, &CreateDefaultProvider);
+  return g_provider;
+}
+
+}  // namespace
+
+namespace grpc {
+namespace testing {
+
+void AddSecureType(const grpc::string& type,
+                   std::unique_ptr<CredentialTypeProvider> type_provider) {
+  GetProvider()->AddSecureType(type, std::move(type_provider));
+}
+
+std::shared_ptr<ChannelCredentials> GetChannelCredentials(
+    const grpc::string& type, ChannelArguments* args) {
+  return GetProvider()->GetChannelCredentials(type, args);
+}
+
+std::shared_ptr<ServerCredentials> GetServerCredentials(
+    const grpc::string& type) {
+  return GetProvider()->GetServerCredentials(type);
+}
+
+std::vector<grpc::string> GetSecureCredentialsTypeList() {
+  return GetProvider()->GetSecureCredentialsTypeList();
+}
+
+}  // namespace testing
+}  // namespace grpc
diff --git a/test/cpp/util/test_credentials_provider.h b/test/cpp/util/test_credentials_provider.h
new file mode 100644
index 0000000..50fadb5
--- /dev/null
+++ b/test/cpp/util/test_credentials_provider.h
@@ -0,0 +1,80 @@
+/*
+ *
+ * Copyright 2016, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef GRPC_TEST_CPP_UTIL_TEST_CREDENTIALS_PROVIDER_H
+#define GRPC_TEST_CPP_UTIL_TEST_CREDENTIALS_PROVIDER_H
+
+#include <memory>
+
+#include <grpc++/security/credentials.h>
+#include <grpc++/security/server_credentials.h>
+#include <grpc++/support/channel_arguments.h>
+
+namespace grpc {
+namespace testing {
+
+const char kInsecureCredentialsType[] = "INSECURE_CREDENTIALS";
+const char kTlsCredentialsType[] = "TLS_CREDENTIALS";
+
+// Provide test credentials of a particular type.
+class CredentialTypeProvider {
+ public:
+  virtual ~CredentialTypeProvider() {}
+
+  virtual std::shared_ptr<ChannelCredentials> GetChannelCredentials(
+      ChannelArguments* args) = 0;
+  virtual std::shared_ptr<ServerCredentials> GetServerCredentials() = 0;
+};
+
+// Add a secure type in addition to the defaults above
+// (kInsecureCredentialsType, kTlsCredentialsType) that can be returned from the
+// functions below.
+void AddSecureType(const grpc::string& type,
+                   std::unique_ptr<CredentialTypeProvider> type_provider);
+
+// Provide channel credentials according to the given type. Alter the channel
+// arguments if needed.
+std::shared_ptr<ChannelCredentials> GetChannelCredentials(
+    const grpc::string& type, ChannelArguments* args);
+
+// Provide server credentials according to the given type.
+std::shared_ptr<ServerCredentials> GetServerCredentials(
+    const grpc::string& type);
+
+// Provide a list of secure credentials type.
+std::vector<grpc::string> GetSecureCredentialsTypeList();
+
+}  // namespace testing
+}  // namespace grpc
+
+#endif  // GRPC_TEST_CPP_UTIL_TEST_CREDENTIALS_PROVIDER_H
diff --git a/test/distrib/csharp/DistribTest.sln b/test/distrib/csharp/DistribTest.sln
index 0eca35c..78d5397 100644
--- a/test/distrib/csharp/DistribTest.sln
+++ b/test/distrib/csharp/DistribTest.sln
@@ -8,13 +8,19 @@
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 		Debug|Any CPU = Debug|Any CPU
+		Debug|x64 = Debug|x64
 		Release|Any CPU = Release|Any CPU
+		Release|x64 = Release|x64
 	EndGlobalSection
 	GlobalSection(ProjectConfigurationPlatforms) = postSolution
 		{A3E61CC3-3710-49A3-A830-A0066EDBCE2F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 		{A3E61CC3-3710-49A3-A830-A0066EDBCE2F}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{A3E61CC3-3710-49A3-A830-A0066EDBCE2F}.Debug|x64.ActiveCfg = Debug|x64
+		{A3E61CC3-3710-49A3-A830-A0066EDBCE2F}.Debug|x64.Build.0 = Debug|x64
 		{A3E61CC3-3710-49A3-A830-A0066EDBCE2F}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{A3E61CC3-3710-49A3-A830-A0066EDBCE2F}.Release|Any CPU.Build.0 = Release|Any CPU
+		{A3E61CC3-3710-49A3-A830-A0066EDBCE2F}.Release|x64.ActiveCfg = Release|x64
+		{A3E61CC3-3710-49A3-A830-A0066EDBCE2F}.Release|x64.Build.0 = Release|x64
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE
diff --git a/test/distrib/csharp/DistribTest/DistribTest.csproj b/test/distrib/csharp/DistribTest/DistribTest.csproj
index 124fc1b..7605495 100644
--- a/test/distrib/csharp/DistribTest/DistribTest.csproj
+++ b/test/distrib/csharp/DistribTest/DistribTest.csproj
@@ -32,6 +32,26 @@
     <ErrorReport>prompt</ErrorReport>
     <WarningLevel>4</WarningLevel>
   </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
+    <DebugSymbols>true</DebugSymbols>
+    <OutputPath>bin\x64\Debug\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <DebugType>full</DebugType>
+    <PlatformTarget>x64</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
+    <Prefer32Bit>true</Prefer32Bit>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
+    <OutputPath>bin\x64\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <Optimize>true</Optimize>
+    <DebugType>pdbonly</DebugType>
+    <PlatformTarget>x64</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
+    <Prefer32Bit>true</Prefer32Bit>
+  </PropertyGroup>
   <ItemGroup>
     <Reference Include="BouncyCastle.Crypto">
       <HintPath>..\packages\BouncyCastle.1.7.0\lib\Net40-Client\BouncyCastle.Crypto.dll</HintPath>
diff --git a/test/distrib/csharp/run_distrib_test.bat b/test/distrib/csharp/run_distrib_test.bat
new file mode 100644
index 0000000..67bfc58
--- /dev/null
+++ b/test/distrib/csharp/run_distrib_test.bat
@@ -0,0 +1,49 @@
+@rem Copyright 2016, Google Inc.
+@rem All rights reserved.
+@rem
+@rem Redistribution and use in source and binary forms, with or without
+@rem modification, are permitted provided that the following conditions are
+@rem met:
+@rem
+@rem     * Redistributions of source code must retain the above copyright
+@rem notice, this list of conditions and the following disclaimer.
+@rem     * Redistributions in binary form must reproduce the above
+@rem copyright notice, this list of conditions and the following disclaimer
+@rem in the documentation and/or other materials provided with the
+@rem distribution.
+@rem     * Neither the name of Google Inc. nor the names of its
+@rem contributors may be used to endorse or promote products derived from
+@rem this software without specific prior written permission.
+@rem
+@rem THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+@rem "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+@rem LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+@rem A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+@rem OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+@rem SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+@rem LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+@rem DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+@rem THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+@rem (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+@rem OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+@rem enter this directory
+cd /d %~dp0
+
+@rem extract input artifacts
+powershell -Command "Add-Type -Assembly 'System.IO.Compression.FileSystem'; [System.IO.Compression.ZipFile]::ExtractToDirectory('../../../input_artifacts/csharp_nugets.zip', 'TestNugetFeed');"
+
+update_version.sh auto
+
+set NUGET=C:\nuget\nuget.exe
+%NUGET% restore || goto :error
+
+@call build_vs2015.bat DistribTest.sln %MSBUILD_EXTRA_ARGS% || goto :error
+
+%DISTRIBTEST_OUTPATH%\DistribTest.exe || goto :error
+
+goto :EOF
+
+:error
+echo Failed!
+exit /b %errorlevel%
diff --git a/test/distrib/csharp/run_distrib_test.sh b/test/distrib/csharp/run_distrib_test.sh
index 1de6204..934174a 100755
--- a/test/distrib/csharp/run_distrib_test.sh
+++ b/test/distrib/csharp/run_distrib_test.sh
@@ -34,9 +34,7 @@
 
 unzip -o "$EXTERNAL_GIT_ROOT/input_artifacts/csharp_nugets.zip" -d TestNugetFeed
 
-# Extract the version number from Grpc nuget package name.
-CSHARP_VERSION=$(ls TestNugetFeed | grep '^Grpc\.[0-9].*\.nupkg$' | sed s/^Grpc\.// | sed s/\.nupkg$//)
-./update_version.sh $CSHARP_VERSION
+./update_version.sh auto
 
 nuget restore
 
diff --git a/test/distrib/csharp/update_version.sh b/test/distrib/csharp/update_version.sh
index f2554e8..b0d0772 100755
--- a/test/distrib/csharp/update_version.sh
+++ b/test/distrib/csharp/update_version.sh
@@ -32,5 +32,13 @@
 
 cd $(dirname $0)
 
+CSHARP_VERSION="$1"
+if [ "$CSHARP_VERSION" == "auto" ]
+then
+  # autodetect C# version
+  CSHARP_VERSION=$(ls TestNugetFeed | grep '^Grpc\.[0-9].*\.nupkg$' | sed s/^Grpc\.// | sed s/\.nupkg$//)
+  echo "Autodetected nuget ${CSHARP_VERSION}"
+fi
+
 # Replaces version placeholder with value provided as first argument.
-sed -ibak "s/__GRPC_NUGET_VERSION__/$1/g" DistribTest/packages.config DistribTest/DistribTest.csproj
+sed -ibak "s/__GRPC_NUGET_VERSION__/${CSHARP_VERSION}/g" DistribTest/packages.config DistribTest/DistribTest.csproj
diff --git a/test/cpp/qps/timer.h b/test/distrib/php/distribtest.php
similarity index 81%
copy from test/cpp/qps/timer.h
copy to test/distrib/php/distribtest.php
index d1aee1a..4c34cd6 100644
--- a/test/cpp/qps/timer.h
+++ b/test/distrib/php/distribtest.php
@@ -1,6 +1,7 @@
+<?php
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,27 +32,14 @@
  *
  */
 
-#ifndef TEST_QPS_TIMER_H
-#define TEST_QPS_TIMER_H
+$channel = new Grpc\Channel('localhost:1000', [
+    'credentials' => Grpc\ChannelCredentials::createInsecure()
+]);
 
-class Timer {
- public:
-  Timer();
+$deadline = Grpc\Timeval::infFuture();
+$call = new Grpc\Call($channel,
+                      'dummy_method',
+                      $deadline);
 
-  struct Result {
-    double wall;
-    double user;
-    double system;
-  };
-
-  Result Mark() const;
-
-  static double Now();
-
- private:
-  static Result Sample();
-
-  const Result start_;
-};
-
-#endif  // TEST_QPS_TIMER_H
+$call->cancel();
+$channel->close();
diff --git a/src/python/grpcio_health_checking/grpc/health/v1alpha/__init__.py b/test/distrib/php/run_distrib_test.sh
old mode 100644
new mode 100755
similarity index 86%
copy from src/python/grpcio_health_checking/grpc/health/v1alpha/__init__.py
copy to test/distrib/php/run_distrib_test.sh
index 7086519..43b28d8
--- a/src/python/grpcio_health_checking/grpc/health/v1alpha/__init__.py
+++ b/test/distrib/php/run_distrib_test.sh
@@ -1,4 +1,5 @@
-# Copyright 2015, Google Inc.
+#!/bin/bash
+# Copyright 2015-2016, Google Inc.
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
@@ -27,4 +28,12 @@
 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
+set -ex
 
+cd $(dirname $0)
+
+cp -r $EXTERNAL_GIT_ROOT/input_artifacts/grpc-php.tgz .
+
+pecl install grpc-php.tgz
+
+php -d extension=grpc.so -d max_execution_time=300 distribtest.php
diff --git a/third_party/nanopb b/third_party/nanopb
new file mode 160000
index 0000000..f8ac463
--- /dev/null
+++ b/third_party/nanopb
@@ -0,0 +1 @@
+Subproject commit f8ac463766281625ad710900479130c7fcb4d63b
diff --git a/tools/buildgen/build-cleaner.py b/tools/buildgen/build-cleaner.py
index 49a3644..12054da 100755
--- a/tools/buildgen/build-cleaner.py
+++ b/tools/buildgen/build-cleaner.py
@@ -40,6 +40,7 @@
 _TOP_LEVEL_KEYS = ['settings', 'proto_deps', 'filegroups', 'libs', 'targets', 'vspackages']
 _ELEM_KEYS = [
     'name',
+    'gtest',
     'cpu_cost',
     'flaky',
     'build',
@@ -98,4 +99,3 @@
   else:
     with open(filename, 'w') as f:
       f.write(output)
-
diff --git a/tools/buildgen/generate_projects.py b/tools/buildgen/generate_projects.py
index 965dd29..0602d93 100755
--- a/tools/buildgen/generate_projects.py
+++ b/tools/buildgen/generate_projects.py
@@ -45,12 +45,12 @@
 os.chdir(os.path.join(os.path.dirname(sys.argv[0]), '..', '..'))
 
 argp = argparse.ArgumentParser()
-argp.add_argument('json', nargs='+')
+argp.add_argument('build_files', nargs='+', default=[])
 argp.add_argument('--templates', nargs='+', default=[])
 argp.add_argument('--jobs', '-j', default=multiprocessing.cpu_count(), type=int)
 args = argp.parse_args()
 
-json = args.json
+json = args.build_files
 
 test = {} if 'TEST' in os.environ else None
 
@@ -62,21 +62,31 @@
     for f in files:
       templates.append(os.path.join(root, f))
 
+pre_jobs = []
+base_cmd = ['python2.7', 'tools/buildgen/mako_renderer.py']
+cmd = base_cmd[:]
+for plugin in plugins:
+  cmd.append('-p')
+  cmd.append(plugin)
+for js in json:
+  cmd.append('-d')
+  cmd.append(js)
+cmd.append('-w')
+preprocessed_build = '.preprocessed_build'
+cmd.append(preprocessed_build)
+pre_jobs.append(jobset.JobSpec(cmd, shortname='preprocess', timeout_seconds=None))
+
 jobs = []
-for template in templates:
+for template in reversed(sorted(templates)):
   root, f = os.path.split(template)
   if os.path.splitext(f)[1] == '.template':
     out_dir = '.' + root[len('templates'):]
     out = out_dir + '/' + os.path.splitext(f)[0]
     if not os.path.exists(out_dir):
       os.makedirs(out_dir)
-    cmd = ['python2.7', 'tools/buildgen/mako_renderer.py']
-    for plugin in plugins:
-      cmd.append('-p')
-      cmd.append(plugin)
-    for js in json:
-      cmd.append('-d')
-      cmd.append(js)
+    cmd = base_cmd[:]
+    cmd.append('-P')
+    cmd.append(preprocessed_build)
     cmd.append('-o')
     if test is None:
       cmd.append(out)
@@ -88,6 +98,7 @@
     cmd.append(root + '/' + f)
     jobs.append(jobset.JobSpec(cmd, shortname=out, timeout_seconds=None))
 
+jobset.run(pre_jobs, maxjobs=args.jobs)
 jobset.run(jobs, maxjobs=args.jobs)
 
 if test is not None:
diff --git a/tools/buildgen/mako_renderer.py b/tools/buildgen/mako_renderer.py
index f1b28d3..5f23f12 100755
--- a/tools/buildgen/mako_renderer.py
+++ b/tools/buildgen/mako_renderer.py
@@ -1,5 +1,5 @@
 #!/usr/bin/env python2.7
-# Copyright 2015, Google Inc.
+# Copyright 2015-2016, Google Inc.
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
@@ -38,6 +38,7 @@
 import getopt
 import imp
 import os
+import cPickle as pickle
 import shutil
 import sys
 
@@ -66,21 +67,23 @@
 
 
 def showhelp():
-  out('mako-renderer.py [-o out] [-m cache] [-d dict] [-d dict...] template')
+  out('mako-renderer.py [-o out] [-m cache] [-P preprocessed_input] [-d dict] [-d dict...]'
+      ' [-t template] [-w preprocessed_output]')
 
 
 def main(argv):
   got_input = False
   module_directory = None
+  preprocessed_output = None
   dictionary = {}
   json_dict = {}
   got_output = False
-  output_file = sys.stdout
   plugins = []
   output_name = None
+  got_preprocessed_input = False
 
   try:
-    opts, args = getopt.getopt(argv, 'hm:d:o:p:')
+    opts, args = getopt.getopt(argv, 'hm:d:o:p:t:P:w:')
   except getopt.GetoptError:
     out('Unknown option')
     showhelp()
@@ -104,18 +107,31 @@
         showhelp()
         sys.exit(4)
       module_directory = arg
+    elif opt == '-P':
+      assert not got_preprocessed_input
+      assert json_dict == {}
+      sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(sys.argv[0]), 'plugins')))
+      with open(arg, 'r') as dict_file:
+        dictionary = pickle.load(dict_file)
+      got_preprocessed_input = True
     elif opt == '-d':
-      dict_file = open(arg, 'r')
-      bunch.merge_json(json_dict, yaml.load(dict_file.read()))
-      dict_file.close()
+      assert not got_preprocessed_input
+      with open(arg, 'r') as dict_file:
+        bunch.merge_json(json_dict, yaml.load(dict_file.read()))
     elif opt == '-p':
       plugins.append(import_plugin(arg))
+    elif opt == '-w':
+      preprocessed_output = arg
 
-  for plugin in plugins:
-    plugin.mako_plugin(json_dict)
+  if not got_preprocessed_input:
+    for plugin in plugins:
+      plugin.mako_plugin(json_dict)
+    for k, v in json_dict.items():
+      dictionary[k] = bunch.to_bunch(v)
 
-  for k, v in json_dict.items():
-    dictionary[k] = bunch.to_bunch(v)
+  if preprocessed_output:
+    with open(preprocessed_output, 'w') as dict_file:
+      pickle.dump(dictionary, dict_file)
 
   cleared_dir = False
   for arg in args:
@@ -168,11 +184,9 @@
           with open(item_output_name, 'w') as output_file:
             template.render_context(Context(output_file, **args))
 
-  if not got_input:
+  if not got_input and not preprocessed_output:
     out('Got nothing to do')
     showhelp()
 
-  output_file.close()
-
 if __name__ == '__main__':
   main(sys.argv[1:])
diff --git a/tools/buildgen/plugins/expand_bin_attrs.py b/tools/buildgen/plugins/expand_bin_attrs.py
index 735c60e..c30df2a 100755
--- a/tools/buildgen/plugins/expand_bin_attrs.py
+++ b/tools/buildgen/plugins/expand_bin_attrs.py
@@ -52,6 +52,7 @@
     tgt['ci_platforms'] = sorted(tgt.get('ci_platforms', tgt['platforms']))
     tgt['boringssl'] = tgt.get('boringssl', False)
     tgt['zlib'] = tgt.get('zlib', False)
+    tgt['gtest'] = tgt.get('gtest', False)
 
   libs = dictionary.get('libs')
   for lib in libs:
diff --git a/tools/codegen/core/gen_load_balancing_proto.sh b/tools/codegen/core/gen_load_balancing_proto.sh
new file mode 100755
index 0000000..fb6a468
--- /dev/null
+++ b/tools/codegen/core/gen_load_balancing_proto.sh
@@ -0,0 +1,138 @@
+#!/bin/bash
+
+# Copyright 2016, Google Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#     * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+#     * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#
+# Example usage:
+#   tools/codegen/core/gen_load_balancing_proto.sh \
+#     src/proto/grpc/lb/v0/load_balancer.proto
+
+read -r -d '' COPYRIGHT <<'EOF'
+/*
+ *
+ * Copyright <YEAR>, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+EOF
+
+CURRENT_YEAR=$(date +%Y)
+COPYRIGHT_FILE=$(mktemp)
+echo "${COPYRIGHT/<YEAR>/$CURRENT_YEAR}" > $COPYRIGHT_FILE
+
+set -ex
+if [ $# -eq 0 ]; then
+  echo "Usage: $0 <load_balancer.proto> [output dir]"
+  exit 1
+fi
+
+readonly GRPC_ROOT=$PWD
+
+OUTPUT_DIR="$GRPC_ROOT/src/core/proto/grpc/lb/v0"
+if [ $# -eq 2 ]; then
+  mkdir -p "$2"
+  if [ $? != 0 ]; then
+    echo "Error creating output directory $2"
+    exit 2
+  fi
+  OUTPUT_DIR="$2"
+fi
+
+readonly EXPECTED_OPTIONS_FILE_PATH="${1%.*}.options"
+
+if [[ ! -f "$1" ]]; then
+  echo "Input proto file '$1' doesn't exist."
+  exit 3
+fi
+if [[ ! -f "${EXPECTED_OPTIONS_FILE_PATH}" ]]; then
+  echo "Expected nanopb options file '${EXPECTED_OPTIONS_FILE_PATH}' missing"
+  exit 4
+fi
+
+readonly VENV_DIR=$(mktemp -d)
+readonly VENV_NAME="nanopb-$(date '+%Y%m%d_%H%M%S_%N')"
+pushd $VENV_DIR
+virtualenv $VENV_NAME
+. $VENV_NAME/bin/activate
+popd
+
+# this should be the same version as the submodule we compile against
+# ideally we'd update this as a template to ensure that
+pip install protobuf==3.0.0b2
+
+pushd "$(dirname $1)" > /dev/null
+
+protoc \
+--plugin=protoc-gen-nanopb="$GRPC_ROOT/third_party/nanopb/generator/protoc-gen-nanopb" \
+--nanopb_out='-T -L#include\ \"third_party/nanopb/pb.h\"'":$OUTPUT_DIR" \
+"$(basename $1)"
+
+readonly PROTO_BASENAME=$(basename $1 .proto)
+sed -i "s:$PROTO_BASENAME.pb.h:src/core/proto/grpc/lb/v0/$PROTO_BASENAME.pb.h:g" \
+    "$OUTPUT_DIR/$PROTO_BASENAME.pb.c"
+
+# prepend copyright
+TMPFILE=$(mktemp)
+cat $COPYRIGHT_FILE "$OUTPUT_DIR/$PROTO_BASENAME.pb.c" > $TMPFILE
+mv -v $TMPFILE "$OUTPUT_DIR/$PROTO_BASENAME.pb.c"
+cat $COPYRIGHT_FILE "$OUTPUT_DIR/$PROTO_BASENAME.pb.h" > $TMPFILE
+mv -v $TMPFILE "$OUTPUT_DIR/$PROTO_BASENAME.pb.h"
+
+deactivate
+rm -rf $VENV_DIR
+
+popd > /dev/null
diff --git a/examples/python/route_guide/run_client.sh b/tools/distrib/check_nanopb_output.sh
similarity index 60%
copy from examples/python/route_guide/run_client.sh
copy to tools/distrib/check_nanopb_output.sh
index e5fd383..5f49ebb 100755
--- a/examples/python/route_guide/run_client.sh
+++ b/tools/distrib/check_nanopb_output.sh
@@ -1,5 +1,5 @@
 #!/bin/bash
-# Copyright 2015, Google Inc.
+# Copyright 2015-2016, Google Inc.
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
@@ -28,9 +28,41 @@
 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-# This is where you have cloned out the https://github.com/grpc/grpc repository
-# And built gRPC Python.
-# ADJUST THIS PATH TO WHERE YOUR ACTUAL LOCATION IS
-GRPC_ROOT=~/github/grpc
+set -ex
 
-$GRPC_ROOT/python2.7_virtual_environment/bin/python -B route_guide_client.py
+apt-get install -y autoconf automake libtool curl python-virtualenv
+
+readonly NANOPB_TMP_OUTPUT="$(mktemp -d)"
+
+# install protoc version 3
+pushd third_party/protobuf
+./autogen.sh
+./configure
+make
+make install
+ldconfig
+popd
+
+if [ ! -x "/usr/local/bin/protoc" ]; then
+  echo "Error: protoc not found in path"
+  exit 1
+fi
+readonly PROTOC_PATH='/usr/local/bin'
+# stack up and change to nanopb's proto generator directory
+pushd third_party/nanopb/generator/proto
+PATH="$PROTOC_PATH:$PATH" make
+
+# back to the root directory
+popd
+
+
+# nanopb-compile the proto to a temp location
+PATH="$PROTOC_PATH:$PATH" ./tools/codegen/core/gen_load_balancing_proto.sh \
+  src/proto/grpc/lb/v0/load_balancer.proto \
+  $NANOPB_TMP_OUTPUT
+
+# compare outputs to checked compiled code
+if ! diff -r $NANOPB_TMP_OUTPUT src/core/proto/grpc/lb/v0; then
+  echo "Outputs differ: $NANOPB_TMP_OUTPUT vs src/core/proto/grpc/lb/v0"
+  exit 2
+fi
diff --git a/src/python/grpcio_health_checking/grpc/health/v1alpha/__init__.py b/tools/dockerfile/distribtest/php_jessie_x64/Dockerfile
similarity index 91%
copy from src/python/grpcio_health_checking/grpc/health/v1alpha/__init__.py
copy to tools/dockerfile/distribtest/php_jessie_x64/Dockerfile
index 7086519..d5d3fd6 100644
--- a/src/python/grpcio_health_checking/grpc/health/v1alpha/__init__.py
+++ b/tools/dockerfile/distribtest/php_jessie_x64/Dockerfile
@@ -1,4 +1,4 @@
-# Copyright 2015, Google Inc.
+# Copyright 2015-2016, Google Inc.
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
@@ -27,4 +27,6 @@
 # (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 debian:jessie
 
+RUN apt-get update && apt-get install -y php5 php5-dev php-pear phpunit
diff --git a/tools/dockerfile/distribtest/python_fedora20_x64/Dockerfile b/tools/dockerfile/distribtest/python_fedora20_x64/Dockerfile
index d580364..5e6cb15 100644
--- a/tools/dockerfile/distribtest/python_fedora20_x64/Dockerfile
+++ b/tools/dockerfile/distribtest/python_fedora20_x64/Dockerfile
@@ -30,3 +30,8 @@
 FROM fedora:20
 
 RUN yum clean all && yum update -y && yum install -y python python-pip
+
+# Upgrading six would fail because of docker issue when using overlay.
+# Trying twice makes it work fine.
+# https://github.com/docker/docker/issues/10180
+RUN pip install --upgrade six || pip install --upgrade six
diff --git a/tools/dockerfile/distribtest/python_fedora21_x64/Dockerfile b/tools/dockerfile/distribtest/python_fedora21_x64/Dockerfile
index 1eb4c1e..f1b0e2f 100644
--- a/tools/dockerfile/distribtest/python_fedora21_x64/Dockerfile
+++ b/tools/dockerfile/distribtest/python_fedora21_x64/Dockerfile
@@ -35,3 +35,8 @@
 RUN yum install -y yum-plugin-ovl
 
 RUN yum clean all && yum update -y && yum install -y python python-pip
+
+# Upgrading six would fail because of docker issue when using overlay.
+# Trying twice makes it work fine.
+# https://github.com/docker/docker/issues/10180
+RUN pip2 install --upgrade six || pip2 install --upgrade six
diff --git a/tools/dockerfile/distribtest/ruby_centos6_x64/Dockerfile b/tools/dockerfile/distribtest/ruby_centos6_x64/Dockerfile
index f65b869..b943b67 100644
--- a/tools/dockerfile/distribtest/ruby_centos6_x64/Dockerfile
+++ b/tools/dockerfile/distribtest/ruby_centos6_x64/Dockerfile
@@ -35,7 +35,9 @@
 
 # Install rvm
 RUN gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3
-RUN \curl -sSL https://get.rvm.io | bash -s stable --ruby
+# Running the installation twice to work around docker issue when using overlay.
+# https://github.com/docker/docker/issues/10180
+RUN (curl -sSL https://get.rvm.io | bash -s stable --ruby) || (curl -sSL https://get.rvm.io | bash -s stable --ruby)
 
 RUN /bin/bash -l -c "echo '. /etc/profile.d/rvm.sh' >> ~/.bashrc"
 RUN /bin/bash -l -c "gem install --update bundler"
diff --git a/tools/dockerfile/grpc_artifact_linux_x64/Dockerfile b/tools/dockerfile/grpc_artifact_linux_x64/Dockerfile
index 41dc427..d048b72 100644
--- a/tools/dockerfile/grpc_artifact_linux_x64/Dockerfile
+++ b/tools/dockerfile/grpc_artifact_linux_x64/Dockerfile
@@ -91,6 +91,13 @@
 RUN /bin/bash -l -c "echo 'rvm --default use ruby-2.1' >> ~/.bashrc"
 RUN /bin/bash -l -c "gem install bundler --no-ri --no-rdoc"
 
+
+##################
+# PHP dependencies
+
+RUN apt-get update && apt-get install -y \
+    php5 php5-dev php-pear phpunit
+
 RUN mkdir /var/local/jenkins
 
 # Define the default command.
diff --git a/tools/dockerfile/grpc_artifact_protoc/Dockerfile b/tools/dockerfile/grpc_artifact_protoc/Dockerfile
new file mode 100644
index 0000000..1bbc6e0
--- /dev/null
+++ b/tools/dockerfile/grpc_artifact_protoc/Dockerfile
@@ -0,0 +1,63 @@
+# Copyright 2016, Google Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#     * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+#     * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+# Docker file for building protoc and gRPC protoc plugin artifacts.
+# forked from https://github.com/google/protobuf/blob/master/protoc-artifacts/Dockerfile
+
+FROM centos:6.6
+
+RUN yum install -y git \
+                   tar \
+                   wget \
+                   make \
+                   autoconf \
+                   curl-devel \
+                   unzip \
+                   automake \
+                   libtool \
+                   glibc-static.i686 \
+                   glibc-devel \
+                   glibc-devel.i686
+
+# Install GCC 4.7 to support -static-libstdc++
+RUN wget http://people.centos.org/tru/devtools-1.1/devtools-1.1.repo -P /etc/yum.repos.d
+RUN bash -c 'echo "enabled=1" >> /etc/yum.repos.d/devtools-1.1.repo'
+RUN bash -c "sed -e 's/\$basearch/i386/g' /etc/yum.repos.d/devtools-1.1.repo > /etc/yum.repos.d/devtools-i386-1.1.repo"
+RUN sed -e 's/testing-/testing-i386-/g' -i /etc/yum.repos.d/devtools-i386-1.1.repo
+
+# We'll get and "Rpmdb checksum is invalid: dCDPT(pkg checksums)" error caused by
+# docker issue when using overlay storage driver, but all the stuff we need
+# will be installed, so for now we just ignore the error.
+# https://github.com/docker/docker/issues/10180
+RUN yum install -y devtoolset-1.1 \
+                   devtoolset-1.1-libstdc++-devel \
+                   devtoolset-1.1-libstdc++-devel.i686 || true
+
+# Start in devtoolset environment that uses GCC 4.7
+CMD ["scl", "enable", "devtoolset-1.1", "bash"]
diff --git a/tools/dockerfile/grpc_clang_format/clang_format_all_the_things.sh b/tools/dockerfile/grpc_clang_format/clang_format_all_the_things.sh
index dd8ea1a..d56bc01 100755
--- a/tools/dockerfile/grpc_clang_format/clang_format_all_the_things.sh
+++ b/tools/dockerfile/grpc_clang_format/clang_format_all_the_things.sh
@@ -44,7 +44,7 @@
 do
   for glob in $GLOB
   do
-    files="$files `find /local-code/$dir -name $glob -and -not -name *.generated.*`"
+    files="$files `find /local-code/$dir -name $glob -and -not -name *.generated.* -and -not -name *.pb.h -and -not -name *.pb.c`"
   done
 done
 
diff --git a/tools/dockerfile/grpc_interop_stress_cxx/Dockerfile b/tools/dockerfile/grpc_interop_stress_cxx/Dockerfile
index 58a8c32..4123cc1 100644
--- a/tools/dockerfile/grpc_interop_stress_cxx/Dockerfile
+++ b/tools/dockerfile/grpc_interop_stress_cxx/Dockerfile
@@ -59,6 +59,8 @@
   wget \
   zip && apt-get clean
 
+RUN easy_install -U pip
+
 # Prepare ccache
 RUN ln -s /usr/bin/ccache /usr/local/bin/gcc
 RUN ln -s /usr/bin/ccache /usr/local/bin/g++
@@ -71,5 +73,8 @@
 # C++ dependencies
 RUN apt-get update && apt-get -y install libgflags-dev libgtest-dev libc++-dev clang
 
+# Google Cloud platform API libraries (for BigQuery)
+RUN pip install --upgrade google-api-python-client
+
 # Define the default command.
 CMD ["bash"]
diff --git a/tools/dockerfile/grpc_interop_stress_cxx/build_interop_stress.sh b/tools/dockerfile/grpc_interop_stress_cxx/build_interop_stress.sh
index 6ed3ccb..392bdfc 100755
--- a/tools/dockerfile/grpc_interop_stress_cxx/build_interop_stress.sh
+++ b/tools/dockerfile/grpc_interop_stress_cxx/build_interop_stress.sh
@@ -42,4 +42,4 @@
 make install-certs
 
 # build C++ interop stress client, interop client and server
-make stress_test interop_client interop_server
+make stress_test metrics_client interop_client interop_server
diff --git a/tools/dockerfile/test/cxx_squeeze_x64/Dockerfile b/tools/dockerfile/test/cxx_squeeze_x64/Dockerfile
new file mode 100644
index 0000000..b7f95aa
--- /dev/null
+++ b/tools/dockerfile/test/cxx_squeeze_x64/Dockerfile
@@ -0,0 +1,88 @@
+# Copyright 2016, Google Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#     * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+#     * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+FROM debian:squeeze
+
+# Install Git and basic packages.
+RUN apt-get update && apt-get install -y \
+  autoconf \
+  autotools-dev \
+  build-essential \
+  bzip2 \
+  ccache \
+  curl \
+  gcc \
+  gcc-multilib \
+  git \
+  gyp \
+  lcov \
+  libc6 \
+  libc6-dbg \
+  libc6-dev \
+  libgtest-dev \
+  libtool \
+  make \
+  perl \
+  strace \
+  python-dev \
+  python-setuptools \
+  python-yaml \
+  telnet \
+  unzip \
+  wget \
+  zip && apt-get clean
+
+#================
+# Build profiling
+RUN apt-get update && apt-get install -y time && apt-get clean
+
+
+# libgflags-dev is not available on squeezy
+RUN apt-get update && apt-get -y install libgtest-dev libc++-dev clang && apt-get clean
+
+RUN apt-get update && apt-get -y install python-pip && apt-get clean
+RUN pip install argparse
+
+RUN wget http://openssl.org/source/openssl-1.0.2f.tar.gz
+
+ENV POST_GIT_STEP tools/dockerfile/test/cxx_squeeze_x64/post-git-setup.sh
+
+# Prepare ccache
+RUN ln -s /usr/bin/ccache /usr/local/bin/gcc
+RUN ln -s /usr/bin/ccache /usr/local/bin/g++
+RUN ln -s /usr/bin/ccache /usr/local/bin/cc
+RUN ln -s /usr/bin/ccache /usr/local/bin/c++
+RUN ln -s /usr/bin/ccache /usr/local/bin/clang
+RUN ln -s /usr/bin/ccache /usr/local/bin/clang++
+
+
+RUN mkdir /var/local/jenkins
+
+# Define the default command.
+CMD ["bash"]
diff --git a/src/python/grpcio_health_checking/grpc/health/v1alpha/__init__.py b/tools/dockerfile/test/cxx_squeeze_x64/post-git-setup.sh
old mode 100644
new mode 100755
similarity index 90%
copy from src/python/grpcio_health_checking/grpc/health/v1alpha/__init__.py
copy to tools/dockerfile/test/cxx_squeeze_x64/post-git-setup.sh
index 7086519..dfde93b
--- a/src/python/grpcio_health_checking/grpc/health/v1alpha/__init__.py
+++ b/tools/dockerfile/test/cxx_squeeze_x64/post-git-setup.sh
@@ -1,4 +1,5 @@
-# Copyright 2015, Google Inc.
+#!/bin/bash
+# Copyright 2016, Google Inc.
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
@@ -27,4 +28,8 @@
 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
+set -ex
 
+cd /var/local/git/grpc
+cp /openssl-1.0.2f.tar.gz third_party
+./tools/openssl/use_openssl.sh
diff --git a/tools/dockerfile/test/cxx_ubuntu1604_x64/Dockerfile b/tools/dockerfile/test/cxx_ubuntu1604_x64/Dockerfile
new file mode 100644
index 0000000..c6fe79b
--- /dev/null
+++ b/tools/dockerfile/test/cxx_ubuntu1604_x64/Dockerfile
@@ -0,0 +1,86 @@
+# Copyright 2015-2016, Google Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#     * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+#     * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+FROM ubuntu:16.04
+
+# Install Git and basic packages.
+RUN apt-get update && apt-get install -y \
+  autoconf \
+  autotools-dev \
+  build-essential \
+  bzip2 \
+  ccache \
+  curl \
+  gcc \
+  gcc-multilib \
+  git \
+  golang \
+  gyp \
+  lcov \
+  libc6 \
+  libc6-dbg \
+  libc6-dev \
+  libgtest-dev \
+  libtool \
+  make \
+  perl \
+  strace \
+  python-dev \
+  python-setuptools \
+  python-yaml \
+  telnet \
+  unzip \
+  wget \
+  zip && apt-get clean
+
+#================
+# Build profiling
+RUN apt-get update && apt-get install -y time && apt-get clean
+
+#=================
+# C++ dependencies
+RUN apt-get update && apt-get -y install libgflags-dev libgtest-dev libc++-dev clang && apt-get clean
+
+# Prepare ccache
+RUN ln -s /usr/bin/ccache /usr/local/bin/gcc
+RUN ln -s /usr/bin/ccache /usr/local/bin/g++
+RUN ln -s /usr/bin/ccache /usr/local/bin/cc
+RUN ln -s /usr/bin/ccache /usr/local/bin/c++
+RUN ln -s /usr/bin/ccache /usr/local/bin/clang
+RUN ln -s /usr/bin/ccache /usr/local/bin/clang++
+
+#======================
+# Zookeeper dependencies
+# TODO(jtattermusch): is zookeeper still needed?
+RUN apt-get install -y libzookeeper-mt-dev
+
+RUN mkdir /var/local/jenkins
+
+# Define the default command.
+CMD ["bash"]
diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal
index 7338ac5..ead8bec 100644
--- a/tools/doxygen/Doxyfile.c++.internal
+++ b/tools/doxygen/Doxyfile.c++.internal
@@ -825,11 +825,11 @@
 src/cpp/client/credentials.cc \
 src/cpp/client/generic_stub.cc \
 src/cpp/client/insecure_credentials.cc \
-src/cpp/common/alarm.cc \
 src/cpp/common/call.cc \
 src/cpp/common/channel_arguments.cc \
 src/cpp/common/completion_queue.cc \
 src/cpp/common/rpc_method.cc \
+src/cpp/proto/proto_serializer.cc \
 src/cpp/proto/proto_utils.cc \
 src/cpp/server/async_generic_service.cc \
 src/cpp/server/create_default_thread_pool.cc \
diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal
index 3927d67..040abc0 100644
--- a/tools/doxygen/Doxyfile.core.internal
+++ b/tools/doxygen/Doxyfile.core.internal
@@ -767,20 +767,6 @@
 include/grpc/grpc.h \
 include/grpc/status.h \
 include/grpc/census.h \
-src/core/security/auth_filters.h \
-src/core/security/base64.h \
-src/core/security/credentials.h \
-src/core/security/handshake.h \
-src/core/security/json_token.h \
-src/core/security/jwt_verifier.h \
-src/core/security/secure_endpoint.h \
-src/core/security/security_connector.h \
-src/core/security/security_context.h \
-src/core/tsi/fake_transport_security.h \
-src/core/tsi/ssl_transport_security.h \
-src/core/tsi/ssl_types.h \
-src/core/tsi/transport_security.h \
-src/core/tsi/transport_security_interface.h \
 src/core/census/grpc_filter.h \
 src/core/channel/channel_args.h \
 src/core/channel/channel_stack.h \
@@ -795,6 +781,7 @@
 src/core/client_config/client_config.h \
 src/core/client_config/connector.h \
 src/core/client_config/initial_connect_string.h \
+src/core/client_config/lb_policies/load_balancer_api.h \
 src/core/client_config/lb_policies/pick_first.h \
 src/core/client_config/lb_policies/round_robin.h \
 src/core/client_config/lb_policy.h \
@@ -845,7 +832,6 @@
 src/core/iomgr/time_averaged_stats.h \
 src/core/iomgr/timer.h \
 src/core/iomgr/timer_heap.h \
-src/core/iomgr/timer_internal.h \
 src/core/iomgr/udp_server.h \
 src/core/iomgr/wakeup_fd_pipe.h \
 src/core/iomgr/wakeup_fd_posix.h \
@@ -856,6 +842,7 @@
 src/core/json/json_common.h \
 src/core/json/json_reader.h \
 src/core/json/json_writer.h \
+src/core/proto/grpc/lb/v0/load_balancer.pb.h \
 src/core/statistics/census_interface.h \
 src/core/statistics/census_rpc_stats.h \
 src/core/surface/api_trace.h \
@@ -895,30 +882,27 @@
 src/core/transport/static_metadata.h \
 src/core/transport/transport.h \
 src/core/transport/transport_impl.h \
+src/core/security/auth_filters.h \
+src/core/security/b64.h \
+src/core/security/credentials.h \
+src/core/security/handshake.h \
+src/core/security/json_token.h \
+src/core/security/jwt_verifier.h \
+src/core/security/secure_endpoint.h \
+src/core/security/security_connector.h \
+src/core/security/security_context.h \
+src/core/tsi/fake_transport_security.h \
+src/core/tsi/ssl_transport_security.h \
+src/core/tsi/ssl_types.h \
+src/core/tsi/transport_security.h \
+src/core/tsi/transport_security_interface.h \
 src/core/census/aggregation.h \
-src/core/census/log.h \
+src/core/census/mlog.h \
 src/core/census/rpc_metric_id.h \
-src/core/httpcli/httpcli_security_connector.c \
-src/core/security/base64.c \
-src/core/security/client_auth_filter.c \
-src/core/security/credentials.c \
-src/core/security/credentials_metadata.c \
-src/core/security/credentials_posix.c \
-src/core/security/credentials_win32.c \
-src/core/security/google_default_credentials.c \
-src/core/security/handshake.c \
-src/core/security/json_token.c \
-src/core/security/jwt_verifier.c \
-src/core/security/secure_endpoint.c \
-src/core/security/security_connector.c \
-src/core/security/security_context.c \
-src/core/security/server_auth_filter.c \
-src/core/security/server_secure_chttp2.c \
-src/core/surface/init_secure.c \
-src/core/surface/secure_channel_create.c \
-src/core/tsi/fake_transport_security.c \
-src/core/tsi/ssl_transport_security.c \
-src/core/tsi/transport_security.c \
+third_party/nanopb/pb.h \
+third_party/nanopb/pb_common.h \
+third_party/nanopb/pb_decode.h \
+third_party/nanopb/pb_encode.h \
 src/core/census/grpc_context.c \
 src/core/census/grpc_filter.c \
 src/core/channel/channel_args.c \
@@ -934,6 +918,7 @@
 src/core/client_config/connector.c \
 src/core/client_config/default_initial_connect_string.c \
 src/core/client_config/initial_connect_string.c \
+src/core/client_config/lb_policies/load_balancer_api.c \
 src/core/client_config/lb_policies/pick_first.c \
 src/core/client_config/lb_policies/round_robin.c \
 src/core/client_config/lb_policy.c \
@@ -948,7 +933,7 @@
 src/core/client_config/subchannel_factory.c \
 src/core/client_config/subchannel_index.c \
 src/core/client_config/uri_parser.c \
-src/core/compression/algorithm.c \
+src/core/compression/compression_algorithm.c \
 src/core/compression/message_compress.c \
 src/core/debug/trace.c \
 src/core/httpcli/format_request.c \
@@ -998,6 +983,7 @@
 src/core/json/json_reader.c \
 src/core/json/json_string.c \
 src/core/json/json_writer.c \
+src/core/proto/grpc/lb/v0/load_balancer.pb.c \
 src/core/surface/alarm.c \
 src/core/surface/api_trace.c \
 src/core/surface/byte_buffer.c \
@@ -1047,12 +1033,36 @@
 src/core/transport/static_metadata.c \
 src/core/transport/transport.c \
 src/core/transport/transport_op_string.c \
+src/core/httpcli/httpcli_security_connector.c \
+src/core/security/b64.c \
+src/core/security/client_auth_filter.c \
+src/core/security/credentials.c \
+src/core/security/credentials_metadata.c \
+src/core/security/credentials_posix.c \
+src/core/security/credentials_win32.c \
+src/core/security/google_default_credentials.c \
+src/core/security/handshake.c \
+src/core/security/json_token.c \
+src/core/security/jwt_verifier.c \
+src/core/security/secure_endpoint.c \
+src/core/security/security_connector.c \
+src/core/security/security_context.c \
+src/core/security/server_auth_filter.c \
+src/core/security/server_secure_chttp2.c \
+src/core/surface/init_secure.c \
+src/core/surface/secure_channel_create.c \
+src/core/tsi/fake_transport_security.c \
+src/core/tsi/ssl_transport_security.c \
+src/core/tsi/transport_security.c \
 src/core/census/context.c \
 src/core/census/initialize.c \
-src/core/census/log.c \
+src/core/census/mlog.c \
 src/core/census/operation.c \
 src/core/census/placeholders.c \
 src/core/census/tracing.c \
+third_party/nanopb/pb_common.c \
+third_party/nanopb/pb_decode.c \
+third_party/nanopb/pb_encode.c \
 include/grpc/support/alloc.h \
 include/grpc/support/atm.h \
 include/grpc/support/atm_gcc_atomic.h \
@@ -1098,13 +1108,14 @@
 src/core/profiling/timers.h \
 src/core/support/block_annotate.h \
 src/core/support/env.h \
-src/core/support/file.h \
+src/core/support/load_file.h \
 src/core/support/murmur_hash.h \
 src/core/support/stack_lockfree.h \
 src/core/support/string.h \
 src/core/support/string_win32.h \
 src/core/support/thd_internal.h \
 src/core/support/time_precise.h \
+src/core/support/tmpfile.h \
 src/core/profiling/basic_timers.c \
 src/core/profiling/stap_timers.c \
 src/core/support/alloc.c \
@@ -1117,11 +1128,9 @@
 src/core/support/env_linux.c \
 src/core/support/env_posix.c \
 src/core/support/env_win32.c \
-src/core/support/file.c \
-src/core/support/file_posix.c \
-src/core/support/file_win32.c \
 src/core/support/histogram.c \
 src/core/support/host_port.c \
+src/core/support/load_file.c \
 src/core/support/log.c \
 src/core/support/log_android.c \
 src/core/support/log_linux.c \
@@ -1147,6 +1156,8 @@
 src/core/support/time_precise.c \
 src/core/support/time_win32.c \
 src/core/support/tls_pthread.c \
+src/core/support/tmpfile_posix.c \
+src/core/support/tmpfile_win32.c \
 src/core/support/wrap_memcpy.c
 
 # This tag can be used to specify the character encoding of the source files
diff --git a/tools/gcp/stress_test/run_client.py b/tools/gcp/stress_test/run_client.py
new file mode 100755
index 0000000..0fa1bf1
--- /dev/null
+++ b/tools/gcp/stress_test/run_client.py
@@ -0,0 +1,187 @@
+#!/usr/bin/env python2.7
+# Copyright 2015-2016, Google Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#     * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+#     * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+import datetime
+import os
+import re
+import select
+import subprocess
+import sys
+import time
+
+from stress_test_utils import EventType
+from stress_test_utils import BigQueryHelper
+
+
+# TODO (sree): Write a python grpc client to directly query the metrics instead
+# of calling metrics_client
+def _get_qps(metrics_cmd):
+  qps = 0
+  try:
+    # Note: gpr_log() writes even non-error messages to stderr stream. So it is 
+    # important that we set stderr=subprocess.STDOUT
+    p = subprocess.Popen(args=metrics_cmd,
+                         stdout=subprocess.PIPE,
+                         stderr=subprocess.STDOUT)
+    retcode = p.wait()
+    (out_str, err_str) = p.communicate()
+    if retcode != 0:
+      print 'Error in reading metrics information'
+      print 'Output: ', out_str
+    else:
+      # The overall qps is printed at the end of the line
+      m = re.search('\d+$', out_str)
+      qps = int(m.group()) if m else 0
+  except Exception as ex:
+    print 'Exception while reading metrics information: ' + str(ex)
+  return qps
+
+
+def run_client():
+  """This is a wrapper around the stress test client and performs the following:
+      1) Create the following two tables in Big Query:
+         (i) Summary table: To record events like the test started, completed
+                            successfully or failed
+        (ii) Qps table: To periodically record the QPS sent by this client
+      2) Start the stress test client and add a row in the Big Query summary
+         table
+      3) Once every few seconds (as specificed by the poll_interval_secs) poll
+         the status of the stress test client process and perform the
+         following:
+          3.1) If the process is still running, get the current qps by invoking
+               the metrics client program and add a row in the Big Query
+               Qps table. Sleep for a duration specified by poll_interval_secs
+          3.2) If the process exited successfully, add a row in the Big Query
+               Summary table and exit
+          3.3) If the process failed, add a row in Big Query summary table and
+               wait forever.
+               NOTE: This script typically runs inside a GKE pod which means
+               that the pod gets destroyed when the script exits. However, in
+               case the stress test client fails, we would not want the pod to
+               be destroyed (since we might want to connect to the pod for
+               examining logs). This is the reason why the script waits forever
+               in case of failures
+  """
+  env = dict(os.environ)
+  image_type = env['STRESS_TEST_IMAGE_TYPE']
+  image_name = env['STRESS_TEST_IMAGE']
+  args_str = env['STRESS_TEST_ARGS_STR']
+  metrics_client_image = env['METRICS_CLIENT_IMAGE']
+  metrics_client_args_str = env['METRICS_CLIENT_ARGS_STR']
+  run_id = env['RUN_ID']
+  pod_name = env['POD_NAME']
+  logfile_name = env.get('LOGFILE_NAME')
+  poll_interval_secs = float(env['POLL_INTERVAL_SECS'])
+  project_id = env['GCP_PROJECT_ID']
+  dataset_id = env['DATASET_ID']
+  summary_table_id = env['SUMMARY_TABLE_ID']
+  qps_table_id = env['QPS_TABLE_ID']
+
+  bq_helper = BigQueryHelper(run_id, image_type, pod_name, project_id,
+                             dataset_id, summary_table_id, qps_table_id)
+  bq_helper.initialize()
+
+  # Create BigQuery Dataset and Tables: Summary Table and Metrics Table
+  if not bq_helper.setup_tables():
+    print 'Error in creating BigQuery tables'
+    return
+
+  start_time = datetime.datetime.now()
+
+  logfile = None
+  details = 'Logging to stdout'
+  if logfile_name is not None:
+    print 'Opening logfile: %s ...' % logfile_name
+    details = 'Logfile: %s' % logfile_name
+    logfile = open(logfile_name, 'w')
+
+  # Update status that the test is starting (in the status table)
+  bq_helper.insert_summary_row(EventType.STARTING, details)
+
+  metrics_cmd = [metrics_client_image
+                ] + [x for x in metrics_client_args_str.split()]
+  stress_cmd = [image_name] + [x for x in args_str.split()]
+
+  print 'Launching process %s ...' % stress_cmd
+  stress_p = subprocess.Popen(args=stress_cmd,
+                              stdout=logfile,
+                              stderr=subprocess.STDOUT)
+
+  qps_history = [1, 1, 1]  # Maintain the last 3 qps readings
+  qps_history_idx = 0  # Index into the qps_history list
+
+  is_error = False
+  while True:
+    # Check if stress_client is still running. If so, collect metrics and upload
+    # to BigQuery status table
+    if stress_p.poll() is not None:
+      end_time = datetime.datetime.now().isoformat()
+      event_type = EventType.SUCCESS
+      details = 'End time: %s' % end_time
+      if stress_p.returncode != 0:
+        event_type = EventType.FAILURE
+        details = 'Return code = %d. End time: %s' % (stress_p.returncode,
+                                                      end_time)
+        is_error = True
+      bq_helper.insert_summary_row(event_type, details)
+      print details
+      break
+
+    # Stress client still running. Get metrics
+    qps = _get_qps(metrics_cmd)
+    qps_recorded_at = datetime.datetime.now().isoformat()
+    print 'qps: %d at %s' % (qps, qps_recorded_at)
+
+    # If QPS has been zero for the last 3 iterations, flag it as error and exit
+    qps_history[qps_history_idx] = qps
+    qps_history_idx = (qps_history_idx + 1) % len(qps_history)
+    if sum(qps_history) == 0:
+      details = 'QPS has been zero for the last %d seconds - as of : %s' % (
+          poll_interval_secs * 3, qps_recorded_at)
+      is_error = True
+      bq_helper.insert_summary_row(EventType.FAILURE, details)
+      print details
+      break
+
+    # Upload qps metrics to BiqQuery
+    bq_helper.insert_qps_row(qps, qps_recorded_at)
+
+    time.sleep(poll_interval_secs)
+
+  if is_error:
+    print 'Waiting indefinitely..'
+    select.select([], [], [])
+
+  print 'Completed'
+  return
+
+
+if __name__ == '__main__':
+  run_client()
diff --git a/tools/gcp/stress_test/run_server.py b/tools/gcp/stress_test/run_server.py
new file mode 100755
index 0000000..64322f6
--- /dev/null
+++ b/tools/gcp/stress_test/run_server.py
@@ -0,0 +1,120 @@
+#!/usr/bin/env python2.7
+# Copyright 2015-2016, Google Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#     * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+#     * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+import datetime
+import os
+import select
+import subprocess
+import sys
+import time
+
+from stress_test_utils import BigQueryHelper
+from stress_test_utils import EventType
+
+
+def run_server():
+  """This is a wrapper around the interop server and performs the following:
+      1) Create a 'Summary table' in Big Query to record events like the server
+         started, completed successfully or failed. NOTE: This also creates
+         another table called the QPS table which is currently NOT needed on the
+         server (it is needed on the stress test clients)
+      2) Start the server process and add a row in Big Query summary table
+      3) Wait for the server process to terminate. The server process does not
+         terminate unless there is an error.
+         If the server process terminated with a failure, add a row in Big Query
+         and wait forever.
+         NOTE: This script typically runs inside a GKE pod which means that the
+         pod gets destroyed when the script exits. However, in case the server
+         process fails, we would not want the pod to be destroyed (since we
+         might want to connect to the pod for examining logs). This is the
+         reason why the script waits forever in case of failures.
+  """
+
+  # Read the parameters from environment variables
+  env = dict(os.environ)
+
+  run_id = env['RUN_ID']  # The unique run id for this test
+  image_type = env['STRESS_TEST_IMAGE_TYPE']
+  image_name = env['STRESS_TEST_IMAGE']
+  args_str = env['STRESS_TEST_ARGS_STR']
+  pod_name = env['POD_NAME']
+  project_id = env['GCP_PROJECT_ID']
+  dataset_id = env['DATASET_ID']
+  summary_table_id = env['SUMMARY_TABLE_ID']
+  qps_table_id = env['QPS_TABLE_ID']
+
+  logfile_name = env.get('LOGFILE_NAME')
+
+  print('pod_name: %s, project_id: %s, run_id: %s, dataset_id: %s, '
+        'summary_table_id: %s, qps_table_id: %s') % (
+            pod_name, project_id, run_id, dataset_id, summary_table_id,
+            qps_table_id)
+
+  bq_helper = BigQueryHelper(run_id, image_type, pod_name, project_id,
+                             dataset_id, summary_table_id, qps_table_id)
+  bq_helper.initialize()
+
+  # Create BigQuery Dataset and Tables: Summary Table and Metrics Table
+  if not bq_helper.setup_tables():
+    print 'Error in creating BigQuery tables'
+    return
+
+  start_time = datetime.datetime.now()
+
+  logfile = None
+  details = 'Logging to stdout'
+  if logfile_name is not None:
+    print 'Opening log file: ', logfile_name
+    logfile = open(logfile_name, 'w')
+    details = 'Logfile: %s' % logfile_name
+
+  # Update status that the test is starting (in the status table)
+  bq_helper.insert_summary_row(EventType.STARTING, details)
+
+  stress_cmd = [image_name] + [x for x in args_str.split()]
+
+  print 'Launching process %s ...' % stress_cmd
+  stress_p = subprocess.Popen(args=stress_cmd,
+                              stdout=logfile,
+                              stderr=subprocess.STDOUT)
+
+  returncode = stress_p.wait()
+  if returncode != 0:
+    end_time = datetime.datetime.now().isoformat()
+    event_type = EventType.FAILURE
+    details = 'Returncode: %d; End time: %s' % (returncode, end_time)
+    bq_helper.insert_summary_row(event_type, details)
+    print 'Waiting indefinitely..'
+    select.select([], [], [])
+  return returncode
+
+
+if __name__ == '__main__':
+  run_server()
diff --git a/tools/gcp/stress_test/stress_test_utils.py b/tools/gcp/stress_test/stress_test_utils.py
new file mode 100755
index 0000000..c4b437e
--- /dev/null
+++ b/tools/gcp/stress_test/stress_test_utils.py
@@ -0,0 +1,197 @@
+#!/usr/bin/env python2.7
+# Copyright 2015-2016, Google Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#     * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+#     * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+import datetime
+import json
+import os
+import re
+import select
+import subprocess
+import sys
+import time
+
+# Import big_query_utils module
+bq_utils_dir = os.path.abspath(os.path.join(
+    os.path.dirname(__file__), '../utils'))
+sys.path.append(bq_utils_dir)
+import big_query_utils as bq_utils
+
+
+class EventType:
+  STARTING = 'STARTING'
+  SUCCESS = 'SUCCESS'
+  FAILURE = 'FAILURE'
+
+
+class BigQueryHelper:
+  """Helper class for the stress test wrappers to interact with BigQuery.
+  """
+
+  def __init__(self, run_id, image_type, pod_name, project_id, dataset_id,
+               summary_table_id, qps_table_id):
+    self.run_id = run_id
+    self.image_type = image_type
+    self.pod_name = pod_name
+    self.project_id = project_id
+    self.dataset_id = dataset_id
+    self.summary_table_id = summary_table_id
+    self.qps_table_id = qps_table_id
+
+  def initialize(self):
+    self.bq = bq_utils.create_big_query()
+
+  def setup_tables(self):
+    return bq_utils.create_dataset(self.bq, self.project_id, self.dataset_id) \
+        and self.__create_summary_table() \
+        and self.__create_qps_table()
+
+  def insert_summary_row(self, event_type, details):
+    row_values_dict = {
+        'run_id': self.run_id,
+        'image_type': self.image_type,
+        'pod_name': self.pod_name,
+        'event_date': datetime.datetime.now().isoformat(),
+        'event_type': event_type,
+        'details': details
+    }
+    # row_unique_id is something that uniquely identifies the row (BigQuery uses
+    # it for duplicate detection).
+    row_unique_id = '%s_%s_%s' % (self.run_id, self.pod_name, event_type)
+    row = bq_utils.make_row(row_unique_id, row_values_dict)
+    return bq_utils.insert_rows(self.bq, self.project_id, self.dataset_id,
+                                self.summary_table_id, [row])
+
+  def insert_qps_row(self, qps, recorded_at):
+    row_values_dict = {
+        'run_id': self.run_id,
+        'pod_name': self.pod_name,
+        'recorded_at': recorded_at,
+        'qps': qps
+    }
+
+    # row_unique_id is something that uniquely identifies the row (BigQuery uses
+    # it for duplicate detection).
+    row_unique_id = '%s_%s_%s' % (self.run_id, self.pod_name, recorded_at)
+    row = bq_utils.make_row(row_unique_id, row_values_dict)
+    return bq_utils.insert_rows(self.bq, self.project_id, self.dataset_id,
+                                self.qps_table_id, [row])
+
+  def check_if_any_tests_failed(self, num_query_retries=3):
+    query = ('SELECT event_type FROM %s.%s WHERE run_id = \'%s\' AND '
+             'event_type="%s"') % (self.dataset_id, self.summary_table_id,
+                                   self.run_id, EventType.FAILURE)
+    query_job = bq_utils.sync_query_job(self.bq, self.project_id, query)
+    page = self.bq.jobs().getQueryResults(**query_job['jobReference']).execute(
+        num_retries=num_query_retries)
+    num_failures = int(page['totalRows'])
+    print 'num rows: ', num_failures
+    return num_failures > 0
+
+  def print_summary_records(self, num_query_retries=3):
+    line = '-' * 120
+    print line
+    print 'Summary records'
+    print 'Run Id: ', self.run_id
+    print 'Dataset Id: ', self.dataset_id
+    print line
+    query = ('SELECT pod_name, image_type, event_type, event_date, details'
+             ' FROM %s.%s WHERE run_id = \'%s\' ORDER by event_date;') % (
+                 self.dataset_id, self.summary_table_id, self.run_id)
+    query_job = bq_utils.sync_query_job(self.bq, self.project_id, query)
+
+    print '{:<25} {:<12} {:<12} {:<30} {}'.format(
+        'Pod name', 'Image type', 'Event type', 'Date', 'Details')
+    print line
+    page_token = None
+    while True:
+      page = self.bq.jobs().getQueryResults(
+          pageToken=page_token,
+          **query_job['jobReference']).execute(num_retries=num_query_retries)
+      rows = page.get('rows', [])
+      for row in rows:
+        print '{:<25} {:<12} {:<12} {:<30} {}'.format(
+            row['f'][0]['v'], row['f'][1]['v'], row['f'][2]['v'],
+            row['f'][3]['v'], row['f'][4]['v'])
+      page_token = page.get('pageToken')
+      if not page_token:
+        break
+
+  def print_qps_records(self, num_query_retries=3):
+    line = '-' * 80
+    print line
+    print 'QPS Summary'
+    print 'Run Id: ', self.run_id
+    print 'Dataset Id: ', self.dataset_id
+    print line
+    query = (
+        'SELECT pod_name, recorded_at, qps FROM %s.%s WHERE run_id = \'%s\' '
+        'ORDER by recorded_at;') % (self.dataset_id, self.qps_table_id,
+                                    self.run_id)
+    query_job = bq_utils.sync_query_job(self.bq, self.project_id, query)
+    print '{:<25} {:30} {}'.format('Pod name', 'Recorded at', 'Qps')
+    print line
+    page_token = None
+    while True:
+      page = self.bq.jobs().getQueryResults(
+          pageToken=page_token,
+          **query_job['jobReference']).execute(num_retries=num_query_retries)
+      rows = page.get('rows', [])
+      for row in rows:
+        print '{:<25} {:30} {}'.format(row['f'][0]['v'], row['f'][1]['v'],
+                                       row['f'][2]['v'])
+      page_token = page.get('pageToken')
+      if not page_token:
+        break
+
+  def __create_summary_table(self):
+    summary_table_schema = [
+        ('run_id', 'STRING', 'Test run id'),
+        ('image_type', 'STRING', 'Client or Server?'),
+        ('pod_name', 'STRING', 'GKE pod hosting this image'),
+        ('event_date', 'STRING', 'The date of this event'),
+        ('event_type', 'STRING', 'STARTED/SUCCESS/FAILURE'),
+        ('details', 'STRING', 'Any other relevant details')
+    ]
+    desc = ('The table that contains START/SUCCESS/FAILURE events for '
+            ' the stress test clients and servers')
+    return bq_utils.create_table(self.bq, self.project_id, self.dataset_id,
+                                 self.summary_table_id, summary_table_schema,
+                                 desc)
+
+  def __create_qps_table(self):
+    qps_table_schema = [
+        ('run_id', 'STRING', 'Test run id'),
+        ('pod_name', 'STRING', 'GKE pod hosting this image'),
+        ('recorded_at', 'STRING', 'Metrics recorded at time'),
+        ('qps', 'INTEGER', 'Queries per second')
+    ]
+    desc = 'The table that cointains the qps recorded at various intervals'
+    return bq_utils.create_table(self.bq, self.project_id, self.dataset_id,
+                                 self.qps_table_id, qps_table_schema, desc)
diff --git a/tools/gcp/utils/big_query_utils.py b/tools/gcp/utils/big_query_utils.py
new file mode 100755
index 0000000..7bb1e14
--- /dev/null
+++ b/tools/gcp/utils/big_query_utils.py
@@ -0,0 +1,140 @@
+#!/usr/bin/env python2.7
+# Copyright 2015-2016, Google Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#     * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+#     * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+import argparse
+import json
+import uuid
+import httplib2
+
+from apiclient import discovery
+from apiclient.errors import HttpError
+from oauth2client.client import GoogleCredentials
+
+NUM_RETRIES = 3
+
+
+def create_big_query():
+  """Authenticates with cloud platform and gets a BiqQuery service object
+  """
+  creds = GoogleCredentials.get_application_default()
+  return discovery.build('bigquery', 'v2', credentials=creds)
+
+
+def create_dataset(biq_query, project_id, dataset_id):
+  is_success = True
+  body = {
+      'datasetReference': {
+          'projectId': project_id,
+          'datasetId': dataset_id
+      }
+  }
+
+  try:
+    dataset_req = biq_query.datasets().insert(projectId=project_id, body=body)
+    dataset_req.execute(num_retries=NUM_RETRIES)
+  except HttpError as http_error:
+    if http_error.resp.status == 409:
+      print 'Warning: The dataset %s already exists' % dataset_id
+    else:
+      # Note: For more debugging info, print "http_error.content"
+      print 'Error in creating dataset: %s. Err: %s' % (dataset_id, http_error)
+      is_success = False
+  return is_success
+
+
+def create_table(big_query, project_id, dataset_id, table_id, table_schema,
+                 description):
+  is_success = True
+
+  body = {
+      'description': description,
+      'schema': {
+          'fields': [{
+              'name': field_name,
+              'type': field_type,
+              'description': field_description
+          } for (field_name, field_type, field_description) in table_schema]
+      },
+      'tableReference': {
+          'datasetId': dataset_id,
+          'projectId': project_id,
+          'tableId': table_id
+      }
+  }
+
+  try:
+    table_req = big_query.tables().insert(projectId=project_id,
+                                          datasetId=dataset_id,
+                                          body=body)
+    res = table_req.execute(num_retries=NUM_RETRIES)
+    print 'Successfully created %s "%s"' % (res['kind'], res['id'])
+  except HttpError as http_error:
+    if http_error.resp.status == 409:
+      print 'Warning: Table %s already exists' % table_id
+    else:
+      print 'Error in creating table: %s. Err: %s' % (table_id, http_error)
+      is_success = False
+  return is_success
+
+
+def insert_rows(big_query, project_id, dataset_id, table_id, rows_list):
+  is_success = True
+  body = {'rows': rows_list}
+  try:
+    insert_req = big_query.tabledata().insertAll(projectId=project_id,
+                                                 datasetId=dataset_id,
+                                                 tableId=table_id,
+                                                 body=body)
+    print body
+    res = insert_req.execute(num_retries=NUM_RETRIES)
+    print res
+  except HttpError as http_error:
+    print 'Error in inserting rows in the table %s' % table_id
+    is_success = False
+  return is_success
+
+
+def sync_query_job(big_query, project_id, query, timeout=5000):
+  query_data = {'query': query, 'timeoutMs': timeout}
+  query_job = None
+  try:
+    query_job = big_query.jobs().query(
+        projectId=project_id,
+        body=query_data).execute(num_retries=NUM_RETRIES)
+  except HttpError as http_error:
+    print 'Query execute job failed with error: %s' % http_error
+    print http_error.content
+  return query_job
+
+  # List of (column name, column type, description) tuples
+def make_row(unique_row_id, row_values_dict):
+  """row_values_dict is a dictionary of column name and column value.
+  """
+  return {'insertId': unique_row_id, 'json': row_values_dict}
diff --git a/tools/gke/kubernetes_api.py b/tools/gcp/utils/kubernetes_api.py
similarity index 74%
rename from tools/gke/kubernetes_api.py
rename to tools/gcp/utils/kubernetes_api.py
index 7dd3015..e8ddd2f 100755
--- a/tools/gke/kubernetes_api.py
+++ b/tools/gcp/utils/kubernetes_api.py
@@ -1,5 +1,5 @@
 #!/usr/bin/env python2.7
-# Copyright 2015, Google Inc.
+# Copyright 2015-2016, Google Inc.
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
@@ -33,8 +33,9 @@
 
 _REQUEST_TIMEOUT_SECS = 10
 
+
 def _make_pod_config(pod_name, image_name, container_port_list, cmd_list,
-                    arg_list):
+                     arg_list, env_dict):
   """Creates a string containing the Pod defintion as required by the Kubernetes API"""
   body = {
       'kind': 'Pod',
@@ -48,20 +49,23 @@
               {
                   'name': pod_name,
                   'image': image_name,
-                  'ports': []
+                  'ports': [{'containerPort': port,
+                             'protocol': 'TCP'}
+                            for port in container_port_list],
+                  'imagePullPolicy': 'Always'
               }
           ]
       }
   }
-  # Populate the 'ports' list
-  for port in container_port_list:
-    port_entry = {'containerPort': port, 'protocol': 'TCP'}
-    body['spec']['containers'][0]['ports'].append(port_entry)
+
+  env_list = [{'name': k, 'value': v} for (k, v) in env_dict.iteritems()]
+  if len(env_list) > 0:
+    body['spec']['containers'][0]['env'] = env_list
 
   # Add the 'Command' and 'Args' attributes if they are passed.
   # Note:
   #  - 'Command' overrides the ENTRYPOINT in the Docker Image
-  #  - 'Args' override the COMMAND in Docker image (yes, it is confusing!)
+  #  - 'Args' override the CMD in Docker image (yes, it is confusing!)
   if len(cmd_list) > 0:
     body['spec']['containers'][0]['command'] = cmd_list
   if len(arg_list) > 0:
@@ -70,7 +74,7 @@
 
 
 def _make_service_config(service_name, pod_name, service_port_list,
-                        container_port_list, is_headless):
+                         container_port_list, is_headless):
   """Creates a string containing the Service definition as required by the Kubernetes API.
 
   NOTE:
@@ -124,6 +128,7 @@
   print('ERROR: Connection failed. Did you remember to run Kubenetes proxy on '
         'localhost (i.e kubectl proxy --port=<proxy_port>) ?. Error: %s' % msg)
 
+
 def _do_post(post_url, api_name, request_body):
   """Helper to do HTTP POST.
 
@@ -135,7 +140,9 @@
   """
   is_success = True
   try:
-    r = requests.post(post_url, data=request_body, timeout=_REQUEST_TIMEOUT_SECS)
+    r = requests.post(post_url,
+                      data=request_body,
+                      timeout=_REQUEST_TIMEOUT_SECS)
     if r.status_code == requests.codes.conflict:
       print('WARN: Looks like the resource already exists. Api: %s, url: %s' %
             (api_name, post_url))
@@ -143,7 +150,8 @@
       print('ERROR: %s API returned error. HTTP response: (%d) %s' %
             (api_name, r.status_code, r.text))
       is_success = False
-  except(requests.exceptions.Timeout, requests.exceptions.ConnectionError) as e:
+  except (requests.exceptions.Timeout,
+          requests.exceptions.ConnectionError) as e:
     is_success = False
     _print_connection_error(str(e))
   return is_success
@@ -165,7 +173,8 @@
       print('ERROR: %s API returned error. HTTP response: %s' %
             (api_name, r.text))
       is_success = False
-  except(requests.exceptions.Timeout, requests.exceptions.ConnectionError) as e:
+  except (requests.exceptions.Timeout,
+          requests.exceptions.ConnectionError) as e:
     is_success = False
     _print_connection_error(str(e))
   return is_success
@@ -179,12 +188,12 @@
   post_url = 'http://%s:%d/api/v1/namespaces/%s/services' % (
       kube_host, kube_port, namespace)
   request_body = _make_service_config(service_name, pod_name, service_port_list,
-                                     container_port_list, is_headless)
+                                      container_port_list, is_headless)
   return _do_post(post_url, 'Create Service', request_body)
 
 
 def create_pod(kube_host, kube_port, namespace, pod_name, image_name,
-               container_port_list, cmd_list, arg_list):
+               container_port_list, cmd_list, arg_list, env_dict):
   """Creates a Kubernetes Pod.
 
   Note that it is generally NOT considered a good practice to directly create
@@ -200,7 +209,7 @@
   post_url = 'http://%s:%d/api/v1/namespaces/%s/pods' % (kube_host, kube_port,
                                                          namespace)
   request_body = _make_pod_config(pod_name, image_name, container_port_list,
-                                 cmd_list, arg_list)
+                                  cmd_list, arg_list, env_dict)
   return _do_post(post_url, 'Create Pod', request_body)
 
 
@@ -214,3 +223,47 @@
   del_url = 'http://%s:%d/api/v1/namespaces/%s/pods/%s' % (kube_host, kube_port,
                                                            namespace, pod_name)
   return _do_delete(del_url, 'Delete Pod')
+
+
+def create_pod_and_service(kube_host, kube_port, namespace, pod_name,
+                           image_name, container_port_list, cmd_list, arg_list,
+                           env_dict, is_headless_service):
+  """A helper function that creates a pod and a service (if pod creation was successful)."""
+  is_success = create_pod(kube_host, kube_port, namespace, pod_name, image_name,
+                          container_port_list, cmd_list, arg_list, env_dict)
+  if not is_success:
+    print 'Error in creating Pod'
+    return False
+
+  is_success = create_service(
+      kube_host,
+      kube_port,
+      namespace,
+      pod_name,  # Use pod_name for service
+      pod_name,
+      container_port_list,  # Service port list same as container port list
+      container_port_list,
+      is_headless_service)
+  if not is_success:
+    print 'Error in creating Service'
+    return False
+
+  print 'Successfully created the pod/service %s' % pod_name
+  return True
+
+
+def delete_pod_and_service(kube_host, kube_port, namespace, pod_name):
+  """ A helper function that calls delete_pod and delete_service """
+  is_success = delete_pod(kube_host, kube_port, namespace, pod_name)
+  if not is_success:
+    print 'Error in deleting pod %s' % pod_name
+    return False
+
+  # Note: service name assumed to the the same as pod name
+  is_success = delete_service(kube_host, kube_port, namespace, pod_name)
+  if not is_success:
+    print 'Error in deleting service %s' % pod_name
+    return False
+
+  print 'Successfully deleted the Pod/Service: %s' % pod_name
+  return True
diff --git a/tools/jenkins/build_docker_and_run_tests.sh b/tools/jenkins/build_docker_and_run_tests.sh
index e2ac751..458e8ca 100755
--- a/tools/jenkins/build_docker_and_run_tests.sh
+++ b/tools/jenkins/build_docker_and_run_tests.sh
@@ -60,6 +60,9 @@
 # Choose random name for docker container
 CONTAINER_NAME="run_tests_$(uuidgen)"
 
+# Git root as seen by the docker instance
+docker_instance_git_root=/var/local/jenkins/grpc
+
 # Run tests inside docker
 docker run \
   -e "RUN_TESTS_COMMAND=$RUN_TESTS_COMMAND" \
@@ -69,9 +72,10 @@
   -e XDG_CACHE_HOME=/tmp/xdg-cache-home \
   -e THIS_IS_REALLY_NEEDED='see https://github.com/docker/docker/issues/14203 for why docker is awful' \
   -e HOST_GIT_ROOT=$git_root \
+  -e LOCAL_GIT_ROOT=$docker_instance_git_root \
   -e "BUILD_ID=$BUILD_ID" \
   -i $TTY_FLAG \
-  -v "$git_root:/var/local/jenkins/grpc" \
+  -v "$git_root:$docker_instance_git_root" \
   -v /tmp/ccache:/tmp/ccache \
   -v /tmp/npm-cache:/tmp/npm-cache \
   -v /tmp/xdg-cache-home:/tmp/xdg-cache-home \
@@ -82,11 +86,6 @@
   $DOCKER_IMAGE_NAME \
   bash -l "/var/local/jenkins/grpc/$DOCKER_RUN_SCRIPT" || DOCKER_FAILED="true"
 
-if [ "$XML_REPORT" != "" ]
-then
-  docker cp "$CONTAINER_NAME:/var/local/git/grpc/$XML_REPORT" $git_root || true
-fi
-
 docker cp "$CONTAINER_NAME:/var/local/git/grpc/reports.zip" $git_root || true
 unzip -o $git_root/reports.zip -d $git_root || true
 rm -f reports.zip
diff --git a/tools/jenkins/build_interop_stress_image.sh b/tools/jenkins/build_interop_stress_image.sh
index 92f2dab..501dc5b 100755
--- a/tools/jenkins/build_interop_stress_image.sh
+++ b/tools/jenkins/build_interop_stress_image.sh
@@ -35,6 +35,8 @@
 
 # Params:
 #  INTEROP_IMAGE - name of tag of the final interop image
+#  INTEROP_IMAGE_TAG - Optional. If set, the created image will be tagged using
+#    the command: 'docker tag $INTEROP_IMAGE $INTEROP_IMAGE_REPOSITORY_TAG'
 #  BASE_NAME - base name used to locate the base Dockerfile and build script
 #  TTY_FLAG - optional -t flag to make docker allocate tty
 #  BUILD_INTEROP_DOCKER_EXTRA_ARGS - optional args to be passed to the
@@ -77,6 +79,7 @@
   $BASE_IMAGE \
   bash -l /var/local/jenkins/grpc/tools/dockerfile/$BASE_NAME/build_interop_stress.sh \
   && docker commit $CONTAINER_NAME $INTEROP_IMAGE \
+  && ( if [ -n "$INTEROP_IMAGE_REPOSITORY_TAG" ]; then docker tag -f $INTEROP_IMAGE $INTEROP_IMAGE_REPOSITORY_TAG ; fi ) \
   && echo "Successfully built image $INTEROP_IMAGE")
 EXITCODE=$?
 
diff --git a/tools/jenkins/docker_run.sh b/tools/jenkins/docker_run.sh
index df7b657..f04b1cf 100755
--- a/tools/jenkins/docker_run.sh
+++ b/tools/jenkins/docker_run.sh
@@ -42,6 +42,8 @@
   cp -r "$EXTERNAL_GIT_ROOT/$RELATIVE_COPY_PATH"/* "/var/local/git/grpc/$RELATIVE_COPY_PATH"
 fi
 
+$POST_GIT_STEP
+
 if [ -x "$(command -v rvm)" ]
 then
   rvm use ruby-2.1
diff --git a/tools/jenkins/docker_run_tests.sh b/tools/jenkins/docker_run_tests.sh
index 282b857..8d6c42c 100755
--- a/tools/jenkins/docker_run_tests.sh
+++ b/tools/jenkins/docker_run_tests.sh
@@ -45,6 +45,8 @@
 
 mkdir -p reports
 
+$POST_GIT_STEP
+
 exit_code=0
 
 $RUN_TESTS_COMMAND || exit_code=$?
@@ -60,5 +62,6 @@
 cd ..
 
 zip -r reports.zip reports
+find . -name report.xml | xargs zip reports.zip
 
 exit $exit_code
diff --git a/tools/jenkins/run_performance.sh b/tools/jenkins/run_performance.sh
index d7e73d4..fbc0783 100755
--- a/tools/jenkins/run_performance.sh
+++ b/tools/jenkins/run_performance.sh
@@ -1,5 +1,5 @@
 #!/usr/bin/env bash
-# Copyright 2015, Google Inc.
+# Copyright 2015-2016, Google Inc.
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
@@ -47,9 +47,90 @@
 bins/$config/qps_worker -driver_port 10010 &
 PID2=$!
 
+#
+# Put a timeout on these tests
+#
+((sleep 900; kill $$ && killall qps_worker && rm -f /tmp/qps-test.$$ )&)
+
 export QPS_WORKERS="localhost:10000,localhost:10010"
 
-bins/$config/qps_driver
+# big is the size in bytes of large messages (0 is the size otherwise)
+big=65536
 
-kill -2 $PID1 $PID2
+# wide is the number of client channels in multi-channel tests (1 otherwise)
+wide=64
+
+# deep is the number of RPCs outstanding on a channel in non-ping-pong tests
+# (the value used is 1 otherwise)
+deep=100
+
+#
+# Get total core count
+cores=`grep -c ^processor /proc/cpuinfo`
+halfcores=`expr $cores / 2`
+
+for secure in true false; do
+  # Scenario 1: generic async streaming ping-pong (contentionless latency)
+  bins/$config/qps_driver --rpc_type=STREAMING --client_type=ASYNC_CLIENT \
+    --server_type=ASYNC_GENERIC_SERVER --outstanding_rpcs_per_channel=1 \
+    --client_channels=1 --bbuf_req_size=0 --bbuf_resp_size=0 \
+    --async_client_threads=1 --async_server_threads=1 --secure_test=$secure \
+    --num_servers=1 --num_clients=1 \
+    --server_core_limit=$halfcores --client_core_limit=0
+
+  # Scenario 2: generic async streaming "unconstrained" (QPS)
+  bins/$config/qps_driver --rpc_type=STREAMING --client_type=ASYNC_CLIENT \
+    --server_type=ASYNC_GENERIC_SERVER --outstanding_rpcs_per_channel=$deep \
+    --client_channels=$wide --bbuf_req_size=0 --bbuf_resp_size=0 \
+    --async_client_threads=0 --async_server_threads=0 --secure_test=$secure \
+    --num_servers=1 --num_clients=0 \
+    --server_core_limit=$halfcores --client_core_limit=0 |& tee /tmp/qps-test.$$
+
+  # Scenario 2b: QPS with a single server core
+  bins/$config/qps_driver --rpc_type=STREAMING --client_type=ASYNC_CLIENT \
+    --server_type=ASYNC_GENERIC_SERVER --outstanding_rpcs_per_channel=$deep \
+    --client_channels=$wide --bbuf_req_size=0 --bbuf_resp_size=0 \
+    --async_client_threads=0 --async_server_threads=0 --secure_test=$secure \
+    --num_servers=1 --num_clients=0 --server_core_limit=1 --client_core_limit=0
+
+  # Scenario 2c: protobuf-based QPS
+  bins/$config/qps_driver --rpc_type=STREAMING --client_type=ASYNC_CLIENT \
+    --server_type=ASYNC_SERVER --outstanding_rpcs_per_channel=$deep \
+    --client_channels=$wide --simple_req_size=0 --simple_resp_size=0 \
+    --async_client_threads=0 --async_server_threads=0 --secure_test=$secure \
+    --num_servers=1 --num_clients=0 \
+    --server_core_limit=$halfcores --client_core_limit=0
+
+  # Scenario 3: Latency at sub-peak load (all clients equally loaded)
+  for loadfactor in 0.7; do
+    bins/$config/qps_driver --rpc_type=STREAMING --client_type=ASYNC_CLIENT \
+      --server_type=ASYNC_GENERIC_SERVER --outstanding_rpcs_per_channel=$deep \
+      --client_channels=$wide --bbuf_req_size=0 --bbuf_resp_size=0 \
+      --async_client_threads=0 --async_server_threads=0 --secure_test=$secure \
+      --num_servers=1 --num_clients=0 --poisson_load=`awk -v lf=$loadfactor \
+      '$5 == "QPS:" {print int(lf * $6); exit}' /tmp/qps-test.$$` \
+      --server_core_limit=$halfcores --client_core_limit=0
+  done
+
+  rm /tmp/qps-test.$$
+
+  # Scenario 4: Single-channel bidirectional throughput test (like TCP_STREAM).
+  bins/$config/qps_driver --rpc_type=STREAMING --client_type=ASYNC_CLIENT \
+    --server_type=ASYNC_GENERIC_SERVER --outstanding_rpcs_per_channel=$deep \
+    --client_channels=1 --bbuf_req_size=$big --bbuf_resp_size=$big \
+    --async_client_threads=1 --async_server_threads=1 --secure_test=$secure \
+    --num_servers=1 --num_clients=1 \
+    --server_core_limit=$halfcores --client_core_limit=0
+
+  # Scenario 5: Sync unary ping-pong with protobufs
+  bins/$config/qps_driver --rpc_type=UNARY --client_type=SYNC_CLIENT \
+    --server_type=SYNC_SERVER --outstanding_rpcs_per_channel=1 \
+    --client_channels=1 --simple_req_size=0 --simple_resp_size=0 \
+    --secure_test=$secure --num_servers=1 --num_clients=1 \
+    --server_core_limit=$halfcores --client_core_limit=0
+
+done
+
+bins/$config/qps_driver --quit=true
+
 wait
diff --git a/examples/python/route_guide/run_client.sh b/tools/openssl/use_openssl.sh
similarity index 67%
rename from examples/python/route_guide/run_client.sh
rename to tools/openssl/use_openssl.sh
index e5fd383..3098217 100755
--- a/examples/python/route_guide/run_client.sh
+++ b/tools/openssl/use_openssl.sh
@@ -1,5 +1,6 @@
 #!/bin/bash
-# Copyright 2015, Google Inc.
+
+# Copyright 2015-2016, Google Inc.
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
@@ -28,9 +29,33 @@
 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-# This is where you have cloned out the https://github.com/grpc/grpc repository
-# And built gRPC Python.
-# ADJUST THIS PATH TO WHERE YOUR ACTUAL LOCATION IS
-GRPC_ROOT=~/github/grpc
+set -ex
 
-$GRPC_ROOT/python2.7_virtual_environment/bin/python -B route_guide_client.py
+cd $(dirname $0)/../..
+set root=`pwd`
+CC=${CC:-cc}
+
+# allow openssl to be pre-downloaded
+if [ ! -e third_party/openssl-1.0.2f.tar.gz ]
+then
+  echo "Downloading http://openssl.org/source/openssl-1.0.2f.tar.gz to third_party/openssl-1.0.2f.tar.gz"
+  wget http://openssl.org/source/openssl-1.0.2f.tar.gz -O third_party/openssl-1.0.2f.tar.gz
+fi
+
+# clean openssl directory
+rm -rf third_party/openssl-1.0.2f
+
+# extract archive
+cd third_party
+tar xfz openssl-1.0.2f.tar.gz
+
+# build openssl
+cd openssl-1.0.2f
+CC="$CC -fPIC -fvisibility=hidden" ./config no-asm
+make
+
+# generate the 'grpc_obj' directory needed by the makefile
+mkdir grpc_obj
+cd grpc_obj
+ar x ../libcrypto.a
+ar x ../libssl.a
diff --git a/tools/run_tests/artifact_targets.py b/tools/run_tests/artifact_targets.py
index 9cd02c5..288a3f0 100644
--- a/tools/run_tests/artifact_targets.py
+++ b/tools/run_tests/artifact_targets.py
@@ -79,6 +79,17 @@
     raise Exception('Unsupported arch')
   return {'CFLAGS': arch_arg, 'LDFLAGS': arch_arg}
 
+_MACOS_COMPAT_FLAG = '-mmacosx-version-min=10.7'
+
+_ARCH_FLAG_MAP = {
+  'x86': '-m32',
+  'x64': '-m64'
+}
+
+python_version_arch_map = {
+  'x86': 'Python27_32bits',
+  'x64': 'Python27'
+}
 
 class PythonArtifact:
   """Builds Python artifacts."""
@@ -88,27 +99,31 @@
     self.platform = platform
     self.arch = arch
     self.labels = ['artifact', 'python', platform, arch]
+    self.python_version = python_version_arch_map[arch]
 
   def pre_build_jobspecs(self):
       return []
 
   def build_jobspec(self):
-    if self.platform == 'windows':
-      raise Exception('Not supported yet.')
+    environ = {}
+    if self.platform == 'linux':
+      if self.arch == 'x86':
+        environ['SETARCH_CMD'] = 'linux32'
+      return create_docker_jobspec(self.name,
+          'tools/dockerfile/grpc_artifact_linux_%s' % self.arch,
+          'tools/run_tests/build_artifact_python.sh',
+          environ=environ)
+    elif self.platform == 'windows':
+      return create_jobspec(self.name,
+                            ['tools\\run_tests\\build_artifact_python.bat',
+                             self.python_version
+                            ],
+                            shell=True)
     else:
-      environ = {}
-      if self.platform == 'linux':
-        if self.arch == 'x86':
-          environ['SETARCH_CMD'] = 'linux32'
-        return create_docker_jobspec(self.name,
-            'tools/dockerfile/grpc_artifact_linux_%s' % self.arch,
-            'tools/run_tests/build_artifact_python.sh',
-            environ=environ)
-      else:
-        environ['SKIP_PIP_INSTALL'] = 'TRUE'
-        return create_jobspec(self.name,
-                              ['tools/run_tests/build_artifact_python.sh'],
-                              environ=environ)
+      environ['SKIP_PIP_INSTALL'] = 'TRUE'
+      return create_jobspec(self.name,
+                            ['tools/run_tests/build_artifact_python.sh'],
+                            environ=environ)
 
   def __str__(self):
     return self.name
@@ -190,6 +205,7 @@
   def __str__(self):
     return self.name
 
+
 node_gyp_arch_map = {
   'x86': 'ia32',
   'x64': 'x64'
@@ -225,16 +241,85 @@
                               ['tools/run_tests/build_artifact_node.sh',
                                self.gyp_arch])
 
+class PHPArtifact:
+  """Builds PHP PECL package"""
+
+  def __init__(self, platform, arch):
+    self.name = 'php_pecl_package_{0}_{1}'.format(platform, arch)
+    self.platform = platform
+    self.arch = arch
+    self.labels = ['artifact', 'php', platform, arch]
+
+  def pre_build_jobspecs(self):
+    return []
+
+  def build_jobspec(self):
+    if self.platform == 'linux':
+      return create_docker_jobspec(
+          self.name,
+          'tools/dockerfile/grpc_artifact_linux_{}'.format(self.arch),
+          'tools/run_tests/build_artifact_php.sh')
+    else:
+      return create_jobspec(self.name,
+                            ['tools/run_tests/build_artifact_php.sh'])
+
+class ProtocArtifact:
+  """Builds protoc and protoc-plugin artifacts"""
+
+  def __init__(self, platform, arch):
+    self.name = 'protoc_%s_%s' % (platform, arch)
+    self.platform = platform
+    self.arch = arch
+    self.labels = ['artifact', 'protoc', platform, arch]
+
+  def pre_build_jobspecs(self):
+      return []
+
+  def build_jobspec(self):
+    if self.platform != 'windows':
+      cxxflags = '-DNDEBUG %s' % _ARCH_FLAG_MAP[self.arch]
+      ldflags = '%s' % _ARCH_FLAG_MAP[self.arch]
+      if self.platform != 'macos':
+        ldflags += '  -static-libgcc -static-libstdc++ -s'
+      environ={'CONFIG': 'opt',
+               'CXXFLAGS': cxxflags,
+               'LDFLAGS': ldflags,
+               'PROTOBUF_LDFLAGS_EXTRA': ldflags}
+      if self.platform == 'linux':
+        return create_docker_jobspec(self.name,
+            'tools/dockerfile/grpc_artifact_protoc',
+            'tools/run_tests/build_artifact_protoc.sh',
+            environ=environ)
+      else:
+        environ['CXXFLAGS'] += ' -std=c++11 -stdlib=libc++ %s' % _MACOS_COMPAT_FLAG
+        return create_jobspec(self.name,
+            ['tools/run_tests/build_artifact_protoc.sh'],
+            environ=environ)
+    else:
+      generator = 'Visual Studio 12 Win64' if self.arch == 'x64' else 'Visual Studio 12' 
+      vcplatform = 'x64' if self.arch == 'x64' else 'Win32'
+      return create_jobspec(self.name,
+                            ['tools\\run_tests\\build_artifact_protoc.bat'],
+                            environ={'generator': generator,
+                                     'Platform': vcplatform})
+
+  def __str__(self):
+    return self.name
+
 
 def targets():
   """Gets list of supported targets"""
   return ([Cls(platform, arch)
-           for Cls in (CSharpExtArtifact, NodeExtArtifact)
+           for Cls in (CSharpExtArtifact, NodeExtArtifact, ProtocArtifact)
            for platform in ('linux', 'macos', 'windows')
            for arch in ('x86', 'x64')] +
           [PythonArtifact('linux', 'x86'),
            PythonArtifact('linux', 'x64'),
            PythonArtifact('macos', 'x64'),
+           PythonArtifact('windows', 'x86'),
+           PythonArtifact('windows', 'x64'),
            RubyArtifact('linux', 'x86'),
            RubyArtifact('linux', 'x64'),
-           RubyArtifact('macos', 'x64')])
+           RubyArtifact('macos', 'x64'),
+           PHPArtifact('linux', 'x64'),
+           PHPArtifact('macos', 'x64')])
diff --git a/src/python/grpcio_health_checking/grpc/health/v1alpha/__init__.py b/tools/run_tests/build_artifact_php.sh
old mode 100644
new mode 100755
similarity index 89%
copy from src/python/grpcio_health_checking/grpc/health/v1alpha/__init__.py
copy to tools/run_tests/build_artifact_php.sh
index 7086519..50bf0ea
--- a/src/python/grpcio_health_checking/grpc/health/v1alpha/__init__.py
+++ b/tools/run_tests/build_artifact_php.sh
@@ -1,4 +1,5 @@
-# Copyright 2015, Google Inc.
+#!/bin/bash
+# Copyright 2016, Google Inc.
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
@@ -27,4 +28,13 @@
 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
+PHP_TARGET_ARCH=$1
+set -ex
 
+cd $(dirname $0)/../..
+
+mkdir -p artifacts
+
+pear package
+
+cp -r grpc-*.tgz artifacts/grpc-php.tgz
diff --git a/tools/run_tests/build_artifact_protoc.bat b/tools/run_tests/build_artifact_protoc.bat
new file mode 100644
index 0000000..e1dc032
--- /dev/null
+++ b/tools/run_tests/build_artifact_protoc.bat
@@ -0,0 +1,51 @@
+@rem Copyright 2016, Google Inc.
+@rem All rights reserved.
+@rem
+@rem Redistribution and use in source and binary forms, with or without
+@rem modification, are permitted provided that the following conditions are
+@rem met:
+@rem
+@rem     * Redistributions of source code must retain the above copyright
+@rem notice, this list of conditions and the following disclaimer.
+@rem     * Redistributions in binary form must reproduce the above
+@rem copyright notice, this list of conditions and the following disclaimer
+@rem in the documentation and/or other materials provided with the
+@rem distribution.
+@rem     * Neither the name of Google Inc. nor the names of its
+@rem contributors may be used to endorse or promote products derived from
+@rem this software without specific prior written permission.
+@rem
+@rem THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+@rem "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+@rem LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+@rem A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+@rem OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+@rem SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+@rem LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+@rem DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+@rem THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+@rem (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+@rem OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+mkdir artifacts
+
+setlocal
+cd third_party/protobuf
+
+powershell -Command "Invoke-WebRequest https://googlemock.googlecode.com/files/gmock-1.7.0.zip -OutFile gmock.zip"
+powershell -Command "Add-Type -Assembly 'System.IO.Compression.FileSystem'; [System.IO.Compression.ZipFile]::ExtractToDirectory('gmock.zip', '.');"
+rename gmock-1.7.0 gmock
+
+cd cmake
+cmake -G "%generator%" || goto :error
+endlocal
+
+call vsprojects/build_plugins.bat || goto :error
+
+xcopy /Y third_party\protobuf\cmake\Release\protoc.exe artifacts\ || goto :error
+xcopy /Y vsprojects\Release\*_plugin.exe artifacts\ || xcopy /Y vsprojects\x64\Release\*_plugin.exe artifacts\ || goto :error
+
+goto :EOF
+
+:error
+exit /b 1
\ No newline at end of file
diff --git a/src/python/grpcio_health_checking/grpc/health/v1alpha/__init__.py b/tools/run_tests/build_artifact_protoc.sh
old mode 100644
new mode 100755
similarity index 84%
copy from src/python/grpcio_health_checking/grpc/health/v1alpha/__init__.py
copy to tools/run_tests/build_artifact_protoc.sh
index 7086519..161d3a8
--- a/src/python/grpcio_health_checking/grpc/health/v1alpha/__init__.py
+++ b/tools/run_tests/build_artifact_protoc.sh
@@ -1,4 +1,5 @@
-# Copyright 2015, Google Inc.
+#!/bin/bash
+# Copyright 2016, Google Inc.
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
@@ -27,4 +28,14 @@
 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
+# Use devtoolset environment that has GCC 4.7 before set -ex
+source scl_source enable devtoolset-1.1
 
+set -ex
+
+cd $(dirname $0)/../..
+
+make plugins
+
+mkdir -p artifacts
+cp bins/opt/protobuf/protoc bins/opt/*_plugin artifacts/
diff --git a/tools/run_tests/build_artifact_python.bat b/tools/run_tests/build_artifact_python.bat
new file mode 100644
index 0000000..023d394
--- /dev/null
+++ b/tools/run_tests/build_artifact_python.bat
@@ -0,0 +1,61 @@
+@rem Copyright 2016, Google Inc.
+@rem All rights reserved.
+@rem
+@rem Redistribution and use in source and binary forms, with or without
+@rem modification, are permitted provided that the following conditions are
+@rem met:
+@rem
+@rem     * Redistributions of source code must retain the above copyright
+@rem notice, this list of conditions and the following disclaimer.
+@rem     * Redistributions in binary form must reproduce the above
+@rem copyright notice, this list of conditions and the following disclaimer
+@rem in the documentation and/or other materials provided with the
+@rem distribution.
+@rem     * Neither the name of Google Inc. nor the names of its
+@rem contributors may be used to endorse or promote products derived from
+@rem this software without specific prior written permission.
+@rem
+@rem THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+@rem "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+@rem LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+@rem A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+@rem OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+@rem SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+@rem LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+@rem DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+@rem THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+@rem (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+@rem OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+set NUGET=C:\nuget\nuget.exe
+%NUGET% restore vsprojects\grpc.sln || goto :error
+
+
+@call vsprojects\build_vs2013.bat vsprojects\grpc.sln /t:grpc_dll /p:Configuration=Release /p:PlatformToolset=v120 /p:Platform=Win32 || goto :error
+@call vsprojects\build_vs2013.bat vsprojects\grpc.sln /t:grpc_dll /p:Configuration=Release /p:PlatformToolset=v120 /p:Platform=x64   || goto :error
+
+mkdir src\python\grpcio\grpc\_cython\_windows
+
+copy /Y vsprojects\Release\grpc_dll.dll src\python\grpcio\grpc\_cython\_windows\grpc_c.32.python || goto :error
+copy /Y vsprojects\x64\Release\grpc_dll.dll src\python\grpcio\grpc\_cython\_windows\grpc_c.64.python || goto :error
+
+
+set PATH=C:\%1;C:\%1\scripts;%PATH%
+
+pip install --upgrade six
+pip install --upgrade setuptools
+pip install -rrequirements.txt
+
+set GRPC_PYTHON_USE_CUSTOM_BDIST=0
+set GRPC_PYTHON_BUILD_WITH_CYTHON=1
+
+python setup.py bdist_wheel
+
+mkdir artifacts
+xcopy /Y /I /S dist\* artifacts\ || goto :error
+
+goto :EOF
+
+:error
+exit /b 1
diff --git a/tools/run_tests/build_artifact_python.sh b/tools/run_tests/build_artifact_python.sh
index 6e7ab91..7ba04d7 100755
--- a/tools/run_tests/build_artifact_python.sh
+++ b/tools/run_tests/build_artifact_python.sh
@@ -39,6 +39,14 @@
   pip install -rrequirements.txt
 fi
 
+# Build the source distribution first because MANIFEST.in cannot override
+# exclusion of built shared objects among package resources (for some
+# inexplicable reason).
+GRPC_PYTHON_USE_CUSTOM_BDIST=0  \
+GRPC_PYTHON_BUILD_WITH_CYTHON=1 \
+${SETARCH_CMD} python setup.py  \
+    sdist
+
 # The bdist_wheel_grpc_custom command is finicky about command output ordering
 # and thus ought to be run in a shell command separate of others. Further, it
 # trashes the actual bdist_wheel output, so it should be run first so that
@@ -48,11 +56,12 @@
 ${SETARCH_CMD} python setup.py  \
     build_tagged_ext
 
+# Wheel has a bug where directories don't get excluded.
+# https://bitbucket.org/pypa/wheel/issues/99/cannot-exclude-directory
 GRPC_PYTHON_USE_CUSTOM_BDIST=0  \
 GRPC_PYTHON_BUILD_WITH_CYTHON=1 \
 ${SETARCH_CMD} python setup.py  \
-    bdist_wheel                 \
-    sdist
+    bdist_wheel
 
 mkdir -p artifacts
 
diff --git a/src/python/grpcio_health_checking/grpc/health/v1alpha/__init__.py b/tools/run_tests/build_package_php.sh
old mode 100644
new mode 100755
similarity index 86%
copy from src/python/grpcio_health_checking/grpc/health/v1alpha/__init__.py
copy to tools/run_tests/build_package_php.sh
index 7086519..56e3319
--- a/src/python/grpcio_health_checking/grpc/health/v1alpha/__init__.py
+++ b/tools/run_tests/build_package_php.sh
@@ -1,4 +1,5 @@
-# Copyright 2015, Google Inc.
+#!/bin/bash
+# Copyright 2016, Google Inc.
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
@@ -27,4 +28,9 @@
 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
+set -ex
 
+cd $(dirname $0)/../..
+
+mkdir -p artifacts/
+cp -r $EXTERNAL_GIT_ROOT/architecture={x86,x64},language=php,platform={windows,linux,macos}/artifacts/* artifacts/ || true
diff --git a/tools/run_tests/configs.json b/tools/run_tests/configs.json
index 9d7b8a3..cbb8ec5 100644
--- a/tools/run_tests/configs.json
+++ b/tools/run_tests/configs.json
@@ -18,7 +18,7 @@
     "environ": {
       "ASAN_OPTIONS": "detect_leaks=0:color=always"
     }, 
-    "timeout_multiplier": 1.5
+    "timeout_multiplier": 3
   }, 
   {
     "config": "ubsan", 
@@ -48,18 +48,18 @@
       "ASAN_OPTIONS": "detect_leaks=1:color=always", 
       "LSAN_OPTIONS": "suppressions=tools/lsan_suppressions.txt:report_objects=1"
     }, 
-    "timeout_multiplier": 1.5
+    "timeout_multiplier": 3
   }, 
   {
     "config": "tsan", 
     "environ": {
       "TSAN_OPTIONS": "suppressions=tools/tsan_suppressions.txt:halt_on_error=1:second_deadlock_stack=1"
     }, 
-    "timeout_multiplier": 2
+    "timeout_multiplier": 5
   }, 
   {
     "config": "msan", 
-    "timeout_multiplier": 2
+    "timeout_multiplier": 4
   }, 
   {
     "config": "mutrace"
diff --git a/tools/run_tests/distribtest_targets.py b/tools/run_tests/distribtest_targets.py
index 261f44b..34cc1cd 100644
--- a/tools/run_tests/distribtest_targets.py
+++ b/tools/run_tests/distribtest_targets.py
@@ -96,6 +96,15 @@
       return create_jobspec(self.name,
           ['test/distrib/csharp/run_distrib_test.sh'],
           environ={'EXTERNAL_GIT_ROOT': '../../..'})
+    elif self.platform == 'windows':
+      if self.arch == 'x64':
+        environ={'MSBUILD_EXTRA_ARGS': '/p:Platform=x64',
+                 'DISTRIBTEST_OUTPATH': 'DistribTest\\bin\\x64\\Debug'}
+      else:
+        environ={'DISTRIBTEST_OUTPATH': 'DistribTest\\bin\\\Debug'}
+      return create_jobspec(self.name,
+          ['test\\distrib\\csharp\\run_distrib_test.bat'],
+          environ=environ)
     else:
       raise Exception("Not supported yet.")
 
@@ -198,6 +207,37 @@
     return self.name
 
 
+class PHPDistribTest(object):
+  """Tests PHP package"""
+
+  def __init__(self, platform, arch, docker_suffix=None):
+    self.name = 'php_%s_%s_%s' % (platform, arch, docker_suffix)
+    self.platform = platform
+    self.arch = arch
+    self.docker_suffix = docker_suffix
+    self.labels = ['distribtest', 'php', platform, arch, docker_suffix]
+
+  def pre_build_jobspecs(self):
+    return []
+
+  def build_jobspec(self):
+    if self.platform == 'linux':
+      return create_docker_jobspec(self.name,
+                                   'tools/dockerfile/distribtest/php_%s_%s' % (
+                                       self.docker_suffix,
+                                       self.arch),
+                                   'test/distrib/php/run_distrib_test.sh')
+    elif self.platform == 'macos':
+      return create_jobspec(self.name,
+          ['test/distrib/php/run_distrib_test.sh'],
+          environ={'EXTERNAL_GIT_ROOT': '../../..'})
+    else:
+      raise Exception("Not supported yet.")
+
+  def __str__(self):
+    return self.name
+
+
 def targets():
   """Gets list of supported targets"""
   return [CSharpDistribTest('linux', 'x64', 'wheezy'),
@@ -209,6 +249,8 @@
           CSharpDistribTest('linux', 'x64', 'ubuntu1510'),
           CSharpDistribTest('linux', 'x64', 'ubuntu1604'),
           CSharpDistribTest('macos', 'x86'),
+          CSharpDistribTest('windows', 'x86'),
+          CSharpDistribTest('windows', 'x64'),
           PythonDistribTest('linux', 'x64', 'wheezy'),
           PythonDistribTest('linux', 'x64', 'jessie'),
           PythonDistribTest('linux', 'x86', 'jessie'),
@@ -241,7 +283,10 @@
           RubyDistribTest('linux', 'x64', 'ubuntu1510'),
           RubyDistribTest('linux', 'x64', 'ubuntu1604'),
           NodeDistribTest('macos', 'x64', None, '4'),
-          NodeDistribTest('linux', 'x86', 'jessie', '4')
+          NodeDistribTest('macos', 'x64', None, '5'),
+          NodeDistribTest('linux', 'x86', 'jessie', '4'),
+          PHPDistribTest('linux', 'x64', 'jessie'),
+          PHPDistribTest('macos', 'x64'),
           ] + [
             NodeDistribTest('linux', 'x64', os, version)
             for os in ('wheezy', 'jessie', 'ubuntu1204', 'ubuntu1404',
diff --git a/tools/run_tests/jobset.py b/tools/run_tests/jobset.py
index adf178b..a3b246d 100755
--- a/tools/run_tests/jobset.py
+++ b/tools/run_tests/jobset.py
@@ -384,7 +384,8 @@
                 self._travis,
                 self._add_env)
       self._running.add(job)
-      self.resultset[job.GetSpec().shortname] = []
+      if not self.resultset.has_key(job.GetSpec().shortname):
+        self.resultset[job.GetSpec().shortname] = []
     return True
 
   def reap(self):
diff --git a/tools/run_tests/package_targets.py b/tools/run_tests/package_targets.py
index 4ca8279..87bc486 100644
--- a/tools/run_tests/package_targets.py
+++ b/tools/run_tests/package_targets.py
@@ -139,9 +139,27 @@
         'tools/run_tests/build_package_python.sh')
 
 
+class PHPPackage:
+  """Copy PHP PECL package artifact"""
+
+  def __init__(self):
+    self.name = 'php_package'
+    self.labels = ['package', 'php', 'linux']
+
+  def pre_build_jobspecs(self):
+    return []
+
+  def build_jobspec(self):
+    return create_docker_jobspec(
+        self.name,
+        'tools/dockerfile/grpc_artifact_linux_x64',
+        'tools/run_tests/build_package_php.sh')
+
+
 def targets():
   """Gets list of supported targets"""
   return [CSharpPackage(),
           NodePackage(),
           RubyPackage(),
-          PythonPackage()]
+          PythonPackage(),
+          PHPPackage()]
diff --git a/tools/run_tests/post_test_node.bat b/tools/run_tests/post_test_node.bat
new file mode 100644
index 0000000..1a2a549
--- /dev/null
+++ b/tools/run_tests/post_test_node.bat
@@ -0,0 +1,30 @@
+@rem Copyright 2016, Google Inc.
+@rem All rights reserved.
+@rem
+@rem Redistribution and use in source and binary forms, with or without
+@rem modification, are permitted provided that the following conditions are
+@rem met:
+@rem
+@rem     * Redistributions of source code must retain the above copyright
+@rem notice, this list of conditions and the following disclaimer.
+@rem     * Redistributions in binary form must reproduce the above
+@rem copyright notice, this list of conditions and the following disclaimer
+@rem in the documentation and/or other materials provided with the
+@rem distribution.
+@rem     * Neither the name of Google Inc. nor the names of its
+@rem contributors may be used to endorse or promote products derived from
+@rem this software without specific prior written permission.
+@rem
+@rem THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+@rem "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+@rem LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+@rem A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+@rem OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+@rem SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+@rem LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+@rem DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+@rem THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+@rem (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+@rem OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+rmdir node_modules /S /Q
\ No newline at end of file
diff --git a/tools/run_tests/report_utils.py b/tools/run_tests/report_utils.py
index 0032a98..df114e5 100644
--- a/tools/run_tests/report_utils.py
+++ b/tools/run_tests/report_utils.py
@@ -47,7 +47,7 @@
     # that make XML report unparseable.
     filtered_msg = filter(
         lambda x: x in string.printable and x != '\f' and x != '\v',
-        msg.decode(errors='ignore'))
+        msg.decode('UTF-8', 'ignore'))
     if output_format == 'HTML':
       filtered_msg = filtered_msg.replace('"', '&quot;')
     return filtered_msg
diff --git a/tools/run_tests/run_interop_tests.py b/tools/run_tests/run_interop_tests.py
index 76be932..df3ab90 100755
--- a/tools/run_tests/run_interop_tests.py
+++ b/tools/run_tests/run_interop_tests.py
@@ -422,7 +422,7 @@
     time.sleep(2)
 
 
-def cloud_to_prod_jobspec(language, test_case, server_host_name, 
+def cloud_to_prod_jobspec(language, test_case, server_host_name,
                           server_host_detail, docker_image=None, auth=False):
   """Creates jobspec for cloud-to-prod interop test"""
   container_name = None
@@ -441,7 +441,7 @@
   cwd = language.client_cwd
 
   if docker_image:
-    container_name = dockerjob.random_name('interop_client_%s' % 
+    container_name = dockerjob.random_name('interop_client_%s' %
                                            language.safename)
     cmdline = docker_run_cmdline(cmdline,
                                  image=docker_image,
@@ -457,7 +457,7 @@
           cmdline=cmdline,
           cwd=cwd,
           environ=environ,
-          shortname='%s:%s:%s:%s' % (suite_name, server_host_name, language, 
+          shortname='%s:%s:%s:%s' % (suite_name, server_host_name, language,
                                      test_case),
           timeout_seconds=90,
           flake_retries=5 if args.allow_flakes else 0,
@@ -575,18 +575,18 @@
     'percent': 1.0 * passed / (passed + failed)
   }
 
-# A dictionary of prod servers to test. 
+# A dictionary of prod servers to test.
 # Format: server_name: (server_host, server_host_override, errors_allowed)
 # TODO(adelez): implement logic for errors_allowed where if the indicated tests
 # fail, they don't impact the overall test result.
 prod_servers = {
-    'default': ('grpc-test.sandbox.googleapis.com', 
+    'default': ('grpc-test.sandbox.googleapis.com',
                 'grpc-test.sandbox.googleapis.com', False),
-    'gateway_v2': ('grpc-test2.sandbox.googleapis.com', 
+    'gateway_v2': ('grpc-test2.sandbox.googleapis.com',
                    'grpc-test2.sandbox.googleapis.com', True),
-    'cloud_gateway': ('216.239.32.255', 'grpc-test.sandbox.googleapis.com', 
+    'cloud_gateway': ('216.239.32.255', 'grpc-test.sandbox.googleapis.com',
                       False),
-    'cloud_gateway_v2': ('216.239.32.255', 'grpc-test2.sandbox.googleapis.com', 
+    'cloud_gateway_v2': ('216.239.32.255', 'grpc-test2.sandbox.googleapis.com',
                          True)
 }
 
@@ -720,7 +720,7 @@
           if not test_case in language.unimplemented_test_cases():
             if not test_case in _SKIP_ADVANCED + _SKIP_COMPRESSION:
               test_job = cloud_to_prod_jobspec(
-                  language, test_case, server_host_name, 
+                  language, test_case, server_host_name,
                   prod_servers[server_host_name],
                   docker_image=docker_images.get(str(language)))
               jobs.append(test_job)
@@ -728,7 +728,7 @@
       if args.http2_interop:
         for test_case in _HTTP2_TEST_CASES:
           test_job = cloud_to_prod_jobspec(
-              http2Interop, test_case, server_host_name, 
+              http2Interop, test_case, server_host_name,
               prod_servers[server_host_name],
               docker_image=docker_images.get(str(http2Interop)))
           jobs.append(test_job)
@@ -739,7 +739,7 @@
         for test_case in _AUTH_TEST_CASES:
           if not test_case in language.unimplemented_test_cases():
             test_job = cloud_to_prod_jobspec(
-                language, test_case, server_host_name, 
+                language, test_case, server_host_name,
                 prod_servers[server_host_name],
                 docker_image=docker_images.get(str(language)), auth=True)
             jobs.append(test_job)
@@ -802,7 +802,7 @@
   report_utils.render_interop_html_report(
       set([str(l) for l in languages]), servers, _TEST_CASES, _AUTH_TEST_CASES,
       _HTTP2_TEST_CASES, resultset, num_failures,
-      args.cloud_to_prod_auth or args.cloud_to_prod, args.prod_servers, 
+      args.cloud_to_prod_auth or args.cloud_to_prod, args.prod_servers,
       args.http2_interop)
 
 finally:
diff --git a/tools/run_tests/run_node.bat b/tools/run_tests/run_node.bat
index ad9ca14..4177736 100644
--- a/tools/run_tests/run_node.bat
+++ b/tools/run_tests/run_node.bat
@@ -27,6 +27,6 @@
 @rem (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 @rem OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-set JUNIT_REPORT_PATH=src\node\reports.xml
+set JUNIT_REPORT_PATH=src\node\report.xml
 set JUNIT_REPORT_STACK=1
 .\node_modules\.bin\mocha.cmd --reporter mocha-jenkins-reporter --timeout 8000 src\node\test
\ No newline at end of file
diff --git a/tools/run_tests/run_node.sh b/tools/run_tests/run_node.sh
index 178584a..d338900 100755
--- a/tools/run_tests/run_node.sh
+++ b/tools/run_tests/run_node.sh
@@ -58,7 +58,7 @@
   echo '<html><head><meta http-equiv="refresh" content="0;URL=lcov-report/index.html"></head></html>' > \
     ../reports/node_coverage/index.html
 else
-  JUNIT_REPORT_PATH=src/node/reports.xml JUNIT_REPORT_STACK=1 \
+  JUNIT_REPORT_PATH=src/node/report.xml JUNIT_REPORT_STACK=1 \
     ./node_modules/.bin/mocha --timeout $timeout \
     --reporter mocha-jenkins-reporter $test_directory
 fi
diff --git a/tools/run_tests/run_tests.py b/tools/run_tests/run_tests.py
index 0b3efa2..08a5ff0 100755
--- a/tools/run_tests/run_tests.py
+++ b/tools/run_tests/run_tests.py
@@ -55,8 +55,8 @@
 import watch_dirs
 
 
-ROOT = os.path.abspath(os.path.join(os.path.dirname(sys.argv[0]), '../..'))
-os.chdir(ROOT)
+_ROOT = os.path.abspath(os.path.join(os.path.dirname(sys.argv[0]), '../..'))
+os.chdir(_ROOT)
 
 
 _FORCE_ENVIRON_FOR_WRAPPERS = {}
@@ -118,6 +118,16 @@
                 not (travis and tgt['flaky'])]
 
 
+def _check_compiler(compiler, supported_compilers):
+  if compiler not in supported_compilers:
+    raise Exception('Compiler %s not supported.' % compiler)
+
+
+def _is_use_docker_child():
+  """Returns True if running running as a --use_docker child."""
+  return True if os.getenv('RUN_TESTS_COMMAND') else False
+
+
 class CLanguage(object):
 
   def __init__(self, make_target, test_lang):
@@ -125,44 +135,81 @@
     self.platform = platform_string()
     self.test_lang = test_lang
 
-  def test_specs(self, config, args):
+  def configure(self, config, args):
+    self.config = config
+    self.args = args
+    if self.platform == 'windows':
+      self._make_options = [_windows_toolset_option(self.args.compiler),
+                            _windows_arch_option(self.args.arch)]
+    else:
+      self._make_options = []
+      self._docker_distro = self._get_docker_distro(self.args.use_docker,
+                                                    self.args.compiler)
+
+  def test_specs(self):
     out = []
-    binaries = get_c_tests(args.travis, self.test_lang)
+    binaries = get_c_tests(self.args.travis, self.test_lang)
     for target in binaries:
-      if config.build_config in target['exclude_configs']:
+      if self.config.build_config in target['exclude_configs']:
         continue
       if self.platform == 'windows':
         binary = 'vsprojects/%s%s/%s.exe' % (
-            'x64/' if args.arch == 'x64' else '',
-            _WINDOWS_CONFIG[config.build_config],
+            'x64/' if self.args.arch == 'x64' else '',
+            _MSBUILD_CONFIG[self.config.build_config],
             target['name'])
       else:
-        binary = 'bins/%s/%s' % (config.build_config, target['name'])
+        binary = 'bins/%s/%s' % (self.config.build_config, target['name'])
       if os.path.isfile(binary):
-        cmdline = [binary] + target['args']
-        out.append(config.job_spec(cmdline, [binary],
-                                   shortname=' '.join(cmdline),
-                                   cpu_cost=target['cpu_cost'],
-                                   environ={'GRPC_DEFAULT_SSL_ROOTS_FILE_PATH':
-                                            os.path.abspath(os.path.dirname(
-                                                sys.argv[0]) + '/../../src/core/tsi/test_creds/ca.pem')}))
-      elif args.regex == '.*' or platform_string() == 'windows':
+        if 'gtest' in target and target['gtest']:
+          # here we parse the output of --gtest_list_tests to build up a
+          # complete list of the tests contained in a binary
+          # for each test, we then add a job to run, filtering for just that
+          # test
+          with open(os.devnull, 'w') as fnull:
+            tests = subprocess.check_output([binary, '--gtest_list_tests'],
+                                            stderr=fnull)
+          base = None
+          for line in tests.split('\n'):
+            i = line.find('#')
+            if i >= 0: line = line[:i]
+            if not line: continue
+            if line[0] != ' ':
+              base = line.strip()
+            else:
+              assert base is not None
+              assert line[1] == ' '
+              test = base + line.strip()
+              cmdline = [binary] + ['--gtest_filter=%s' % test]
+              out.append(self.config.job_spec(cmdline, [binary],
+                                              shortname='%s:%s' % (binary, test),
+                                              cpu_cost=target['cpu_cost'],
+                                              environ={'GRPC_DEFAULT_SSL_ROOTS_FILE_PATH':
+                                                       _ROOT + '/src/core/tsi/test_creds/ca.pem'}))
+        else:
+          cmdline = [binary] + target['args']
+          out.append(self.config.job_spec(cmdline, [binary],
+                                          shortname=' '.join(cmdline),
+                                          cpu_cost=target['cpu_cost'],
+                                          environ={'GRPC_DEFAULT_SSL_ROOTS_FILE_PATH':
+                                                   _ROOT + '/src/core/tsi/test_creds/ca.pem'}))
+      elif self.args.regex == '.*' or self.platform == 'windows':
         print '\nWARNING: binary not found, skipping', binary
     return sorted(out)
 
-  def make_targets(self, test_regex):
-    if platform_string() != 'windows' and test_regex != '.*':
+  def make_targets(self):
+    test_regex = self.args.regex
+    if self.platform != 'windows' and self.args.regex != '.*':
       # use the regex to minimize the number of things to build
       return [os.path.basename(target['name'])
               for target in get_c_tests(False, self.test_lang)
               if re.search(test_regex, '/' + target['name'])]
-    if platform_string() == 'windows':
+    if self.platform == 'windows':
       # don't build tools on windows just yet
       return ['buildtests_%s' % self.make_target]
     return ['buildtests_%s' % self.make_target, 'tools_%s' % self.make_target]
 
   def make_options(self):
-    return []
+    return self._make_options;
 
   def pre_build_steps(self):
     if self.platform == 'windows':
@@ -182,11 +229,24 @@
   def makefile_name(self):
     return 'Makefile'
 
-  def supports_multi_config(self):
-    return True
+  def _get_docker_distro(self, use_docker, compiler):
+    if _is_use_docker_child():
+      return "already_under_docker"
+    if not use_docker:
+      _check_compiler(compiler, ['default'])
 
-  def dockerfile_dir(self, config, arch):
-    return 'tools/dockerfile/test/cxx_jessie_%s' % _docker_arch_suffix(arch)
+    if compiler == 'gcc4.9' or compiler == 'default':
+      return 'jessie'
+    elif compiler == 'gcc4.4':
+      return 'squeeze'
+    elif compiler == 'gcc5.3':
+      return 'ubuntu1604'
+    else:
+      raise Exception('Compiler %s not supported.' % compiler)
+
+  def dockerfile_dir(self):
+    return 'tools/dockerfile/test/cxx_%s_%s' % (self._docker_distro,
+                                                _docker_arch_suffix(self.args.arch))
 
   def __str__(self):
     return self.make_target
@@ -198,13 +258,18 @@
     self.platform = platform_string()
     self.node_version = '0.12'
 
-  def test_specs(self, config, args):
+  def configure(self, config, args):
+    self.config = config
+    self.args = args
+    _check_compiler(self.args.compiler, ['default'])
+
+  def test_specs(self):
     if self.platform == 'windows':
-      return [config.job_spec(['tools\\run_tests\\run_node.bat'], None)]
+      return [self.config.job_spec(['tools\\run_tests\\run_node.bat'], None)]
     else:
-      return [config.job_spec(['tools/run_tests/run_node.sh', self.node_version],
-                              None,
-                              environ=_FORCE_ENVIRON_FOR_WRAPPERS)]
+      return [self.config.job_spec(['tools/run_tests/run_node.sh', self.node_version],
+                                   None,
+                                   environ=_FORCE_ENVIRON_FOR_WRAPPERS)]
 
   def pre_build_steps(self):
     if self.platform == 'windows':
@@ -212,7 +277,7 @@
     else:
       return [['tools/run_tests/pre_build_node.sh', self.node_version]]
 
-  def make_targets(self, test_regex):
+  def make_targets(self):
     return []
 
   def make_options(self):
@@ -225,16 +290,16 @@
       return [['tools/run_tests/build_node.sh', self.node_version]]
 
   def post_tests_steps(self):
-    return []
+    if self.platform == 'windows':
+      return [['tools\\run_tests\\post_test_node.bat']]
+    else:
+      return []
 
   def makefile_name(self):
     return 'Makefile'
 
-  def supports_multi_config(self):
-    return False
-
-  def dockerfile_dir(self, config, arch):
-    return 'tools/dockerfile/test/node_jessie_%s' % _docker_arch_suffix(arch)
+  def dockerfile_dir(self):
+    return 'tools/dockerfile/test/node_jessie_%s' % _docker_arch_suffix(self.args.arch)
 
   def __str__(self):
     return 'node'
@@ -242,14 +307,19 @@
 
 class PhpLanguage(object):
 
-  def test_specs(self, config, args):
-    return [config.job_spec(['src/php/bin/run_tests.sh'], None,
-                            environ=_FORCE_ENVIRON_FOR_WRAPPERS)]
+  def configure(self, config, args):
+    self.config = config
+    self.args = args
+    _check_compiler(self.args.compiler, ['default'])
+
+  def test_specs(self):
+    return [self.config.job_spec(['src/php/bin/run_tests.sh'], None,
+                                  environ=_FORCE_ENVIRON_FOR_WRAPPERS)]
 
   def pre_build_steps(self):
     return []
 
-  def make_targets(self, test_regex):
+  def make_targets(self):
     return ['static_c', 'shared_c']
 
   def make_options(self):
@@ -264,11 +334,8 @@
   def makefile_name(self):
     return 'Makefile'
 
-  def supports_multi_config(self):
-    return False
-
-  def dockerfile_dir(self, config, arch):
-    return 'tools/dockerfile/test/php_jessie_%s' % _docker_arch_suffix(arch)
+  def dockerfile_dir(self):
+    return 'tools/dockerfile/test/php_jessie_%s' % _docker_arch_suffix(self.args.arch)
 
   def __str__(self):
     return 'php'
@@ -280,10 +347,15 @@
     self._build_python_versions = ['2.7']
     self._has_python_versions = []
 
-  def test_specs(self, config, args):
+  def configure(self, config, args):
+    self.config = config
+    self.args = args
+    _check_compiler(self.args.compiler, ['default'])
+
+  def test_specs(self):
     environment = dict(_FORCE_ENVIRON_FOR_WRAPPERS)
     environment['PYVER'] = '2.7'
-    return [config.job_spec(
+    return [self.config.job_spec(
         ['tools/run_tests/run_python.sh'],
         None,
         environ=environment,
@@ -294,7 +366,7 @@
   def pre_build_steps(self):
     return []
 
-  def make_targets(self, test_regex):
+  def make_targets(self):
     return ['static_c', 'grpc_python_plugin', 'shared_c']
 
   def make_options(self):
@@ -320,11 +392,8 @@
   def makefile_name(self):
     return 'Makefile'
 
-  def supports_multi_config(self):
-    return False
-
-  def dockerfile_dir(self, config, arch):
-    return 'tools/dockerfile/test/python_jessie_%s' % _docker_arch_suffix(arch)
+  def dockerfile_dir(self):
+    return 'tools/dockerfile/test/python_jessie_%s' % _docker_arch_suffix(self.args.arch)
 
   def __str__(self):
     return 'python'
@@ -332,15 +401,20 @@
 
 class RubyLanguage(object):
 
-  def test_specs(self, config, args):
-    return [config.job_spec(['tools/run_tests/run_ruby.sh'], None,
-                            timeout_seconds=10*60,
-                            environ=_FORCE_ENVIRON_FOR_WRAPPERS)]
+  def configure(self, config, args):
+    self.config = config
+    self.args = args
+    _check_compiler(self.args.compiler, ['default'])
+
+  def test_specs(self):
+    return [self.config.job_spec(['tools/run_tests/run_ruby.sh'], None,
+                                 timeout_seconds=10*60,
+                                 environ=_FORCE_ENVIRON_FOR_WRAPPERS)]
 
   def pre_build_steps(self):
     return [['tools/run_tests/pre_build_ruby.sh']]
 
-  def make_targets(self, test_regex):
+  def make_targets(self):
     return []
 
   def make_options(self):
@@ -355,27 +429,30 @@
   def makefile_name(self):
     return 'Makefile'
 
-  def supports_multi_config(self):
-    return False
-
-  def dockerfile_dir(self, config, arch):
-    return 'tools/dockerfile/test/ruby_jessie_%s' % _docker_arch_suffix(arch)
+  def dockerfile_dir(self):
+    return 'tools/dockerfile/test/ruby_jessie_%s' % _docker_arch_suffix(self.args.arch)
 
   def __str__(self):
     return 'ruby'
 
 
 class CSharpLanguage(object):
+
   def __init__(self):
     self.platform = platform_string()
 
-  def test_specs(self, config, args):
+  def configure(self, config, args):
+    self.config = config
+    self.args = args
+    _check_compiler(self.args.compiler, ['default'])
+
+  def test_specs(self):
     with open('src/csharp/tests.json') as f:
       tests_json = json.load(f)
     assemblies = tests_json['assemblies']
     tests = tests_json['tests']
 
-    msbuild_config = _WINDOWS_CONFIG[config.build_config]
+    msbuild_config = _MSBUILD_CONFIG[self.config.build_config]
     assembly_files = ['%s/bin/%s/%s.dll' % (a, msbuild_config, a)
                       for a in assemblies]
 
@@ -387,13 +464,13 @@
     else:
       script_name = 'tools/run_tests/run_csharp.sh'
 
-    if config.build_config == 'gcov':
+    if self.config.build_config == 'gcov':
       # On Windows, we only collect C# code coverage.
       # On Linux, we only collect coverage for native extension.
       # For code coverage all tests need to run as one suite.
-      return [config.job_spec([script_name] + extra_args, None,
-                              shortname='csharp.coverage',
-                              environ=_FORCE_ENVIRON_FOR_WRAPPERS)]
+      return [self.config.job_spec([script_name] + extra_args, None,
+                                    shortname='csharp.coverage',
+                                    environ=_FORCE_ENVIRON_FOR_WRAPPERS)]
     else:
       specs = []
       for test in tests:
@@ -402,9 +479,9 @@
           # use different output directory for each test to prevent
           # TestResult.xml clash between parallel test runs.
           cmdline += ['-work=test-result/%s' % uuid.uuid4()]
-        specs.append(config.job_spec(cmdline, None,
-                                     shortname='csharp.%s' % test,
-                                     environ=_FORCE_ENVIRON_FOR_WRAPPERS))
+        specs.append(self.config.job_spec(cmdline, None,
+                                          shortname='csharp.%s' % test,
+                                          environ=_FORCE_ENVIRON_FOR_WRAPPERS))
       return specs
 
   def pre_build_steps(self):
@@ -413,7 +490,7 @@
     else:
       return [['tools/run_tests/pre_build_csharp.sh']]
 
-  def make_targets(self, test_regex):
+  def make_targets(self):
     # For Windows, this target doesn't really build anything,
     # everything is build by buildall script later.
     if self.platform == 'windows':
@@ -440,11 +517,8 @@
   def makefile_name(self):
     return 'Makefile'
 
-  def supports_multi_config(self):
-    return False
-
-  def dockerfile_dir(self, config, arch):
-    return 'tools/dockerfile/test/csharp_jessie_%s' % _docker_arch_suffix(arch)
+  def dockerfile_dir(self):
+    return 'tools/dockerfile/test/csharp_jessie_%s' % _docker_arch_suffix(self.args.arch)
 
   def __str__(self):
     return 'csharp'
@@ -452,14 +526,19 @@
 
 class ObjCLanguage(object):
 
-  def test_specs(self, config, args):
-    return [config.job_spec(['src/objective-c/tests/run_tests.sh'], None,
-                            environ=_FORCE_ENVIRON_FOR_WRAPPERS)]
+  def configure(self, config, args):
+    self.config = config
+    self.args = args
+    _check_compiler(self.args.compiler, ['default'])
+
+  def test_specs(self):
+    return [self.config.job_spec(['src/objective-c/tests/run_tests.sh'], None,
+                                  environ=_FORCE_ENVIRON_FOR_WRAPPERS)]
 
   def pre_build_steps(self):
     return []
 
-  def make_targets(self, test_regex):
+  def make_targets(self):
     return ['grpc_objective_c_plugin', 'interop_server']
 
   def make_options(self):
@@ -474,10 +553,7 @@
   def makefile_name(self):
     return 'Makefile'
 
-  def supports_multi_config(self):
-    return False
-
-  def dockerfile_dir(self, config, arch):
+  def dockerfile_dir(self):
     return None
 
   def __str__(self):
@@ -486,18 +562,23 @@
 
 class Sanity(object):
 
-  def test_specs(self, config, args):
+  def configure(self, config, args):
+    self.config = config
+    self.args = args
+    _check_compiler(self.args.compiler, ['default'])
+
+  def test_specs(self):
     import yaml
     with open('tools/run_tests/sanity/sanity_tests.yaml', 'r') as f:
-      return [config.job_spec(cmd['script'].split(), None,
-                              timeout_seconds=None, environ={'TEST': 'true'},
-                              cpu_cost=cmd.get('cpu_cost', 1))
+      return [self.config.job_spec(cmd['script'].split(), None,
+                                   timeout_seconds=None, environ={'TEST': 'true'},
+                                   cpu_cost=cmd.get('cpu_cost', 1))
               for cmd in yaml.load(f)]
 
   def pre_build_steps(self):
     return []
 
-  def make_targets(self, test_regex):
+  def make_targets(self):
     return ['run_dep_checks']
 
   def make_options(self):
@@ -512,55 +593,18 @@
   def makefile_name(self):
     return 'Makefile'
 
-  def supports_multi_config(self):
-    return False
-
-  def dockerfile_dir(self, config, arch):
+  def dockerfile_dir(self):
     return 'tools/dockerfile/test/sanity'
 
   def __str__(self):
     return 'sanity'
 
 
-class Build(object):
-
-  def test_specs(self, config, args):
-    return []
-
-  def pre_build_steps(self):
-    return []
-
-  def make_targets(self, test_regex):
-    return ['static']
-
-  def make_options(self):
-    return []
-
-  def build_steps(self):
-    return []
-
-  def post_tests_steps(self):
-    return []
-
-  def makefile_name(self):
-    return 'Makefile'
-
-  def supports_multi_config(self):
-    return True
-
-  def dockerfile_dir(self, config, arch):
-    return None
-
-  def __str__(self):
-    return self.make_target
-
-
 # different configurations we can run under
 with open('tools/run_tests/configs.json') as f:
   _CONFIGS = dict((cfg['config'], Config(**cfg)) for cfg in ast.literal_eval(f.read()))
 
 
-_DEFAULT = ['opt']
 _LANGUAGES = {
     'c++': CLanguage('cxx', 'c++'),
     'c': CLanguage('c', 'c'),
@@ -570,11 +614,11 @@
     'ruby': RubyLanguage(),
     'csharp': CSharpLanguage(),
     'objc' : ObjCLanguage(),
-    'sanity': Sanity(),
-    'build': Build(),
+    'sanity': Sanity()
     }
 
-_WINDOWS_CONFIG = {
+
+_MSBUILD_CONFIG = {
     'dbg': 'Debug',
     'opt': 'Release',
     'gcov': 'Debug',
@@ -651,14 +695,6 @@
     sys.exit(1)
 
 
-def _get_dockerfile_dir(language, cfg, arch):
-  """Returns dockerfile to use"""
-  custom = language.dockerfile_dir(cfg, arch)
-  if custom:
-    return custom
-  else:
-    return 'tools/dockerfile/grpc_tests_multilang_%s' % _docker_arch_suffix(arch)
-
 def runs_per_test_type(arg_str):
     """Auxilary function to parse the "runs_per_test" flag.
 
@@ -682,9 +718,8 @@
 # parse command line
 argp = argparse.ArgumentParser(description='Run grpc tests.')
 argp.add_argument('-c', '--config',
-                  choices=['all'] + sorted(_CONFIGS.keys()),
-                  nargs='+',
-                  default=_DEFAULT)
+                  choices=sorted(_CONFIGS.keys()),
+                  default='opt')
 argp.add_argument('-n', '--runs_per_test', default=1, type=runs_per_test_type,
         help='A positive integer or "inf". If "inf", all tests will run in an '
              'infinite loop. Especially useful in combination with "-f"')
@@ -728,9 +763,11 @@
                   default='default',
                   help='Selects architecture to target. For some platforms "default" is the only supported choice.')
 argp.add_argument('--compiler',
-                  choices=['default', 'vs2010', 'vs2013', 'vs2015'],
+                  choices=['default',
+                           'gcc4.4', 'gcc4.9', 'gcc5.3',
+                           'vs2010', 'vs2013', 'vs2015'],
                   default='default',
-                  help='Selects compiler to use. For some platforms "default" is the only supported choice.')
+                  help='Selects compiler to use. Allowed values depend on the platform and language.')
 argp.add_argument('--build_only',
                   default=False,
                   action='store_const',
@@ -776,11 +813,8 @@
 
 
 # grab config
-run_configs = set(_CONFIGS[cfg]
-                  for cfg in itertools.chain.from_iterable(
-                      _CONFIGS.iterkeys() if x == 'all' else [x]
-                      for x in args.config))
-build_configs = set(cfg.build_config for cfg in run_configs)
+run_config = _CONFIGS[args.config]
+build_config = run_config.build_config
 
 if args.travis:
   _FORCE_ENVIRON_FOR_WRAPPERS = {'GRPC_TRACE': 'api'}
@@ -791,17 +825,13 @@
   lang_list = args.language
 # We don't support code coverage on some languages
 if 'gcov' in args.config:
-  for bad in ['objc', 'sanity', 'build']:
+  for bad in ['objc', 'sanity']:
     if bad in lang_list:
       lang_list.remove(bad)
 
 languages = set(_LANGUAGES[l] for l in lang_list)
-
-if len(build_configs) > 1:
-  for language in languages:
-    if not language.supports_multi_config():
-      print language, 'does not support multiple build configurations'
-      sys.exit(1)
+for l in languages:
+  l.configure(run_config, args)
 
 language_make_options=[]
 if any(language.make_options() for language in languages):
@@ -811,10 +841,6 @@
   else:
     language_make_options = next(iter(languages)).make_options()
 
-if len(languages) != 1 or len(build_configs) != 1:
-  print 'Multi-language and multi-config testing is not supported.'
-  sys.exit(1)
-
 if args.use_docker:
   if not args.travis:
     print 'Seen --use_docker flag, will run tests under docker.'
@@ -824,14 +850,18 @@
     print 'copied to the docker environment.'
     time.sleep(5)
 
+  dockerfile_dirs = set([l.dockerfile_dir() for l in languages])
+  if len(dockerfile_dirs) > 1:
+    print 'Languages to be tested require running under different docker images.'
+    sys.exit(1)
+  dockerfile_dir = next(iter(dockerfile_dirs))
+
   child_argv = [ arg for arg in sys.argv if not arg == '--use_docker' ]
   run_tests_cmd = 'python tools/run_tests/run_tests.py %s' % ' '.join(child_argv[1:])
 
   env = os.environ.copy()
   env['RUN_TESTS_COMMAND'] = run_tests_cmd
-  env['DOCKERFILE_DIR'] = _get_dockerfile_dir(next(iter(languages)),
-                                              next(iter(build_configs)),
-                                              args.arch)
+  env['DOCKERFILE_DIR'] = dockerfile_dir
   env['DOCKER_RUN_SCRIPT'] = 'tools/jenkins/docker_run_tests.sh'
   if args.xml_report:
     env['XML_REPORT'] = args.xml_report
@@ -843,10 +873,6 @@
                         env=env)
   sys.exit(0)
 
-if platform_string() != 'windows' and args.compiler != 'default':
-    print 'Compiler %s not supported on current platform.' % args.compiler
-    sys.exit(1)
-
 _check_arch_option(args.arch)
 
 def make_jobspec(cfg, targets, makefile='Makefile'):
@@ -861,9 +887,7 @@
     return [
       jobset.JobSpec([_windows_build_bat(args.compiler),
                       'vsprojects\\%s.sln' % target,
-                      '/p:Configuration=%s' % _WINDOWS_CONFIG[cfg],
-                      _windows_toolset_option(args.compiler),
-                      _windows_arch_option(args.arch)] +
+                      '/p:Configuration=%s' % _MSBUILD_CONFIG[cfg]] +
                       extra_args +
                       language_make_options,
                       shell=True, timeout_seconds=None)
@@ -886,32 +910,29 @@
 for l in languages:
   makefile = l.makefile_name()
   make_targets[makefile] = make_targets.get(makefile, set()).union(
-      set(l.make_targets(args.regex)))
+      set(l.make_targets()))
 
 def build_step_environ(cfg):
   environ = {'CONFIG': cfg}
-  msbuild_cfg = _WINDOWS_CONFIG.get(cfg)
+  msbuild_cfg = _MSBUILD_CONFIG.get(cfg)
   if msbuild_cfg:
     environ['MSBUILD_CONFIG'] = msbuild_cfg
   return environ
 
 build_steps = list(set(
-                   jobset.JobSpec(cmdline, environ=build_step_environ(cfg), flake_retries=5)
-                   for cfg in build_configs
+                   jobset.JobSpec(cmdline, environ=build_step_environ(build_config), flake_retries=5)
                    for l in languages
                    for cmdline in l.pre_build_steps()))
 if make_targets:
-  make_commands = itertools.chain.from_iterable(make_jobspec(cfg, list(targets), makefile) for cfg in build_configs for (makefile, targets) in make_targets.iteritems())
+  make_commands = itertools.chain.from_iterable(make_jobspec(build_config, list(targets), makefile) for (makefile, targets) in make_targets.iteritems())
   build_steps.extend(set(make_commands))
 build_steps.extend(set(
-                   jobset.JobSpec(cmdline, environ=build_step_environ(cfg), timeout_seconds=None)
-                   for cfg in build_configs
+                   jobset.JobSpec(cmdline, environ=build_step_environ(build_config), timeout_seconds=None)
                    for l in languages
                    for cmdline in l.build_steps()))
 
 post_tests_steps = list(set(
-                        jobset.JobSpec(cmdline, environ=build_step_environ(cfg))
-                        for cfg in build_configs
+                        jobset.JobSpec(cmdline, environ=build_step_environ(build_config))
                         for l in languages
                         for cmdline in l.post_tests_steps()))
 runs_per_test = args.runs_per_test
@@ -1024,7 +1045,7 @@
           print 'last ditch attempt to contact port server succeeded'
           break
         except:
-          traceback.print_exc();
+          traceback.print_exc()
           port_log = open(logfile, 'r').read()
           print port_log
           sys.exit(1)
@@ -1044,7 +1065,7 @@
         time.sleep(1)
         waits += 1
       except:
-        traceback.print_exc();
+        traceback.print_exc()
         port_server.kill()
         raise
 
@@ -1102,9 +1123,8 @@
     infinite_runs = runs_per_test == 0
     one_run = set(
       spec
-      for config in run_configs
       for language in languages
-      for spec in language.test_specs(config, args)
+      for spec in language.test_specs()
       if re.search(args.regex, spec.shortname))
     # When running on travis, we want out test runs to be as similar as possible
     # for reproducibility purposes.
diff --git a/tools/run_tests/sanity/check_sources_and_headers.py b/tools/run_tests/sanity/check_sources_and_headers.py
index 3974af0..44dc49b 100755
--- a/tools/run_tests/sanity/check_sources_and_headers.py
+++ b/tools/run_tests/sanity/check_sources_and_headers.py
@@ -59,25 +59,43 @@
     return True
   return False
 
+def produces_object(name):
+  return os.path.splitext(name)[1] in ['.c', '.cc']
+
+obj_producer_to_source = {'c': {}, 'c++': {}, 'csharp': {}}
+
 errors = 0
 for target in js:
-  for fn in target['src']:
-    with open(os.path.join(root, fn)) as f:
-      src = f.read().splitlines()
-    for line in src:
-      m = re_inc1.match(line)
-      if m:
-        if not target_has_header(target, m.group(1)):
-          print (
-            'target %s (%s) does not name header %s as a dependency' % (
-              target['name'], fn, m.group(1)))
-          errors += 1
-      m = re_inc2.match(line)
-      if m:
-        if not target_has_header(target, 'include/' + m.group(1)):
-          print (
-            'target %s (%s) does not name header %s as a dependency' % (
-              target['name'], fn, m.group(1)))
-          errors += 1
+  if not target['third_party']:
+    for fn in target['src']:
+      with open(os.path.join(root, fn)) as f:
+        src = f.read().splitlines()
+      for line in src:
+        m = re_inc1.match(line)
+        if m:
+          if not target_has_header(target, m.group(1)):
+            print (
+              'target %s (%s) does not name header %s as a dependency' % (
+                target['name'], fn, m.group(1)))
+            errors += 1
+        m = re_inc2.match(line)
+        if m:
+          if not target_has_header(target, 'include/' + m.group(1)):
+            print (
+              'target %s (%s) does not name header %s as a dependency' % (
+                target['name'], fn, m.group(1)))
+            errors += 1
+  if target['type'] == 'lib':
+    for fn in target['src']:
+      language = target['language']
+      if produces_object(fn):
+        obj_base = os.path.splitext(os.path.basename(fn))[0]
+        if obj_base in obj_producer_to_source[language]:
+          if obj_producer_to_source[language][obj_base] != fn:
+            print (
+              'target %s (%s) produces an aliased object file with %s' % (
+                target['name'], fn, obj_producer_to_source[language][obj_base]))
+        else:
+          obj_producer_to_source[language][obj_base] = fn
 
 assert errors == 0
diff --git a/tools/run_tests/sanity/check_submodules.sh b/tools/run_tests/sanity/check_submodules.sh
index f49230e..3c6dbb9 100755
--- a/tools/run_tests/sanity/check_submodules.sh
+++ b/tools/run_tests/sanity/check_submodules.sh
@@ -44,6 +44,7 @@
  9f897b25800d2f54f5c442ef01a60721aeca6d87 third_party/boringssl (version_for_cocoapods_1.0-67-g9f897b2)
  05b155ff59114735ec8cd089f669c4c3d8f59029 third_party/gflags (v2.1.0-45-g05b155f)
  c99458533a9b4c743ed51537e25989ea55944908 third_party/googletest (release-1.7.0)
+ f8ac463766281625ad710900479130c7fcb4d63b third_party/nanopb (nanopb-0.3.4-29-gf8ac463)
  d5fb408ddc281ffcadeb08699e65bb694656d0bd third_party/protobuf (v3.0.0-beta-2)
  50893291621658f355bc5b4d450a8d06a563053d third_party/zlib (v1.2.8)
 EOF
diff --git a/tools/run_tests/sanity/check_version.py b/tools/run_tests/sanity/check_version.py
new file mode 100755
index 0000000..41dd5ef
--- /dev/null
+++ b/tools/run_tests/sanity/check_version.py
@@ -0,0 +1,97 @@
+#!/usr/bin/env python2.7
+
+# Copyright 2016, Google Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#     * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+#     * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+import sys
+import yaml
+import os
+import re
+import subprocess
+
+errors = 0
+
+os.chdir(os.path.join(os.path.dirname(sys.argv[0]), '../../..'))
+
+# hack import paths to pick up extra code
+sys.path.insert(0, os.path.abspath('tools/buildgen/plugins'))
+from expand_version import Version
+
+try:
+  branch_name = subprocess.check_output(
+    'git rev-parse --abbrev-ref HEAD',
+    shell=True)
+except:
+  print 'WARNING: not a git repository'
+  branch_name = None
+
+if branch_name is not None:
+  m = re.match(r'^release-([0-9]+)_([0-9]+)$', branch_name)
+  if m:
+    print 'RELEASE branch'
+    # version number should align with the branched version
+    check_version = lambda version: (
+      version.major == int(m.group(1)) and
+      version.minor == int(m.group(2)))
+    warning = 'Version key "%%s" value "%%s" should have a major version %s and minor version %s' % (m.group(1), m.group(2))
+  elif re.match(r'^debian/.*$', branch_name):
+    # no additional version checks for debian branches
+    check_version = lambda version: True
+  else:
+    # all other branches should have a -dev tag
+    check_version = lambda version: version.tag == 'dev'
+    warning = 'Version key "%s" value "%s" should have a -dev tag'
+else:
+  check_version = lambda version: True
+
+with open('build.yaml', 'r') as f:
+  build_yaml = yaml.load(f.read())
+
+settings = build_yaml['settings']
+
+top_version = Version(settings['version'])
+if not check_version(top_version):
+  errors += 1
+  print warning % ('version', top_version)
+
+for tag, value in settings.iteritems():
+  if re.match(r'^[a-z]+_version$', tag):
+    value = Version(value)
+    if value.major != top_version.major:
+      errors += 1
+      print 'major version mismatch on %s: %d vs %d' % (tag, value.major, top_version.major)
+    if value.minor != top_version.minor:
+      errors += 1
+      print 'minor version mismatch on %s: %d vs %d' % (tag, value.minor, top_version.minor)
+    if not check_version(value):
+      errors += 1
+      print warning % (tag, value)
+
+sys.exit(errors)
+
diff --git a/tools/run_tests/sanity/sanity_tests.yaml b/tools/run_tests/sanity/sanity_tests.yaml
index 809e6ce..cffc180 100644
--- a/tools/run_tests/sanity/sanity_tests.yaml
+++ b/tools/run_tests/sanity/sanity_tests.yaml
@@ -1,9 +1,11 @@
 # a set of tests that are run in parallel for sanity tests
+- script: tools/run_tests/sanity/check_cache_mk.sh
 - script: tools/run_tests/sanity/check_sources_and_headers.py
 - script: tools/run_tests/sanity/check_submodules.sh
-- script: tools/run_tests/sanity/check_cache_mk.sh
+- script: tools/run_tests/sanity/check_version.py
 - script: tools/buildgen/generate_projects.sh -j 3
   cpu_cost: 3
 - script: tools/distrib/check_copyright.py
 - script: tools/distrib/clang_format_code.sh
 - script: tools/distrib/check_trailing_newlines.sh
+- script: tools/distrib/check_nanopb_output.sh
diff --git a/tools/run_tests/sources_and_headers.json b/tools/run_tests/sources_and_headers.json
index ce54430..fd4bbdb 100644
--- a/tools/run_tests/sources_and_headers.json
+++ b/tools/run_tests/sources_and_headers.json
@@ -13,7 +13,9 @@
     "name": "alarm_test", 
     "src": [
       "test/core/surface/alarm_test.c"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -27,7 +29,9 @@
     "name": "algorithm_test", 
     "src": [
       "test/core/compression/algorithm_test.c"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -39,7 +43,9 @@
     "name": "alloc_test", 
     "src": [
       "test/core/support/alloc_test.c"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -53,7 +59,9 @@
     "name": "alpn_test", 
     "src": [
       "test/core/transport/chttp2/alpn_test.c"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -65,7 +73,9 @@
     "name": "bin_encoder_test", 
     "src": [
       "test/core/transport/chttp2/bin_encoder_test.c"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -79,21 +89,9 @@
     "name": "census_context_test", 
     "src": [
       "test/core/census/context_test.c"
-    ]
-  }, 
-  {
-    "deps": [
-      "gpr", 
-      "gpr_test_util", 
-      "grpc", 
-      "grpc_test_util"
     ], 
-    "headers": [], 
-    "language": "c", 
-    "name": "census_log_test", 
-    "src": [
-      "test/core/census/log_test.c"
-    ]
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -107,7 +105,9 @@
     "name": "channel_create_test", 
     "src": [
       "test/core/surface/channel_create_test.c"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -121,7 +121,9 @@
     "name": "chttp2_hpack_encoder_test", 
     "src": [
       "test/core/transport/chttp2/hpack_encoder_test.c"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -135,7 +137,9 @@
     "name": "chttp2_status_conversion_test", 
     "src": [
       "test/core/transport/chttp2/status_conversion_test.c"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -149,7 +153,9 @@
     "name": "chttp2_stream_map_test", 
     "src": [
       "test/core/transport/chttp2/stream_map_test.c"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -163,7 +169,9 @@
     "name": "chttp2_varint_test", 
     "src": [
       "test/core/transport/chttp2/varint_test.c"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -177,7 +185,9 @@
     "name": "compression_test", 
     "src": [
       "test/core/compression/compression_test.c"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -191,7 +201,9 @@
     "name": "dns_resolver_test", 
     "src": [
       "test/core/client_config/resolvers/dns_resolver_test.c"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -205,7 +217,9 @@
     "name": "dualstack_socket_test", 
     "src": [
       "test/core/end2end/dualstack_socket_test.c"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -219,7 +233,9 @@
     "name": "endpoint_pair_test", 
     "src": [
       "test/core/iomgr/endpoint_pair_test.c"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -233,7 +249,9 @@
     "name": "fd_conservation_posix_test", 
     "src": [
       "test/core/iomgr/fd_conservation_posix_test.c"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -247,7 +265,9 @@
     "name": "fd_posix_test", 
     "src": [
       "test/core/iomgr/fd_posix_test.c"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -261,7 +281,9 @@
     "name": "fling_client", 
     "src": [
       "test/core/fling/client.c"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -275,7 +297,9 @@
     "name": "fling_server", 
     "src": [
       "test/core/fling/server.c"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -289,7 +313,9 @@
     "name": "fling_stream_test", 
     "src": [
       "test/core/fling/fling_stream_test.c"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -303,7 +329,9 @@
     "name": "fling_test", 
     "src": [
       "test/core/fling/fling_test.c"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -315,7 +343,9 @@
     "name": "gen_hpack_tables", 
     "src": [
       "tools/codegen/core/gen_hpack_tables.c"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [], 
@@ -324,7 +354,9 @@
     "name": "gen_legal_metadata_characters", 
     "src": [
       "tools/codegen/core/gen_legal_metadata_characters.c"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -336,7 +368,9 @@
     "name": "gpr_avl_test", 
     "src": [
       "test/core/support/avl_test.c"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -348,7 +382,9 @@
     "name": "gpr_cmdline_test", 
     "src": [
       "test/core/support/cmdline_test.c"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -360,7 +396,9 @@
     "name": "gpr_cpu_test", 
     "src": [
       "test/core/support/cpu_test.c"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -372,19 +410,9 @@
     "name": "gpr_env_test", 
     "src": [
       "test/core/support/env_test.c"
-    ]
-  }, 
-  {
-    "deps": [
-      "gpr", 
-      "gpr_test_util"
     ], 
-    "headers": [], 
-    "language": "c", 
-    "name": "gpr_file_test", 
-    "src": [
-      "test/core/support/file_test.c"
-    ]
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -396,7 +424,9 @@
     "name": "gpr_histogram_test", 
     "src": [
       "test/core/support/histogram_test.c"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -408,7 +438,23 @@
     "name": "gpr_host_port_test", 
     "src": [
       "test/core/support/host_port_test.c"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
+  }, 
+  {
+    "deps": [
+      "gpr", 
+      "gpr_test_util"
+    ], 
+    "headers": [], 
+    "language": "c", 
+    "name": "gpr_load_file_test", 
+    "src": [
+      "test/core/support/load_file_test.c"
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -420,7 +466,9 @@
     "name": "gpr_log_test", 
     "src": [
       "test/core/support/log_test.c"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -432,7 +480,9 @@
     "name": "gpr_slice_buffer_test", 
     "src": [
       "test/core/support/slice_buffer_test.c"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -444,7 +494,9 @@
     "name": "gpr_slice_test", 
     "src": [
       "test/core/support/slice_test.c"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -456,7 +508,9 @@
     "name": "gpr_stack_lockfree_test", 
     "src": [
       "test/core/support/stack_lockfree_test.c"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -468,7 +522,9 @@
     "name": "gpr_string_test", 
     "src": [
       "test/core/support/string_test.c"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -480,7 +536,9 @@
     "name": "gpr_sync_test", 
     "src": [
       "test/core/support/sync_test.c"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -492,7 +550,9 @@
     "name": "gpr_thd_test", 
     "src": [
       "test/core/support/thd_test.c"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -504,7 +564,9 @@
     "name": "gpr_time_test", 
     "src": [
       "test/core/support/time_test.c"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -516,7 +578,9 @@
     "name": "gpr_tls_test", 
     "src": [
       "test/core/support/tls_test.c"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -528,7 +592,9 @@
     "name": "gpr_useful_test", 
     "src": [
       "test/core/support/useful_test.c"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -542,7 +608,9 @@
     "name": "grpc_auth_context_test", 
     "src": [
       "test/core/security/auth_context_test.c"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -553,10 +621,12 @@
     ], 
     "headers": [], 
     "language": "c", 
-    "name": "grpc_base64_test", 
+    "name": "grpc_b64_test", 
     "src": [
-      "test/core/security/base64_test.c"
-    ]
+      "test/core/security/b64_test.c"
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -570,7 +640,9 @@
     "name": "grpc_byte_buffer_reader_test", 
     "src": [
       "test/core/surface/byte_buffer_reader_test.c"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -584,7 +656,9 @@
     "name": "grpc_channel_args_test", 
     "src": [
       "test/core/channel/channel_args_test.c"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -598,7 +672,9 @@
     "name": "grpc_channel_stack_test", 
     "src": [
       "test/core/channel/channel_stack_test.c"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -612,7 +688,9 @@
     "name": "grpc_completion_queue_test", 
     "src": [
       "test/core/surface/completion_queue_test.c"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -626,7 +704,9 @@
     "name": "grpc_create_jwt", 
     "src": [
       "test/core/security/create_jwt.c"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -640,7 +720,9 @@
     "name": "grpc_credentials_test", 
     "src": [
       "test/core/security/credentials_test.c"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -654,7 +736,9 @@
     "name": "grpc_fetch_oauth2", 
     "src": [
       "test/core/security/fetch_oauth2.c"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -668,7 +752,9 @@
     "name": "grpc_invalid_channel_args_test", 
     "src": [
       "test/core/surface/invalid_channel_args_test.c"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -682,7 +768,9 @@
     "name": "grpc_json_token_test", 
     "src": [
       "test/core/security/json_token_test.c"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -696,7 +784,9 @@
     "name": "grpc_jwt_verifier_test", 
     "src": [
       "test/core/security/jwt_verifier_test.c"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -710,7 +800,9 @@
     "name": "grpc_print_google_default_creds_token", 
     "src": [
       "test/core/security/print_google_default_creds_token.c"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -724,7 +816,9 @@
     "name": "grpc_security_connector_test", 
     "src": [
       "test/core/security/security_connector_test.c"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -738,7 +832,9 @@
     "name": "grpc_verify_jwt", 
     "src": [
       "test/core/security/verify_jwt.c"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -752,7 +848,9 @@
     "name": "hpack_parser_test", 
     "src": [
       "test/core/transport/chttp2/hpack_parser_test.c"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -766,7 +864,9 @@
     "name": "hpack_table_test", 
     "src": [
       "test/core/transport/chttp2/hpack_table_test.c"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -780,7 +880,9 @@
     "name": "httpcli_format_request_test", 
     "src": [
       "test/core/httpcli/format_request_test.c"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -794,7 +896,9 @@
     "name": "httpcli_parser_test", 
     "src": [
       "test/core/httpcli/parser_test.c"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -808,7 +912,9 @@
     "name": "httpcli_test", 
     "src": [
       "test/core/httpcli/httpcli_test.c"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -822,7 +928,9 @@
     "name": "httpscli_test", 
     "src": [
       "test/core/httpcli/httpscli_test.c"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -836,7 +944,9 @@
     "name": "init_test", 
     "src": [
       "test/core/surface/init_test.c"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -850,7 +960,9 @@
     "name": "invalid_call_argument_test", 
     "src": [
       "test/core/end2end/invalid_call_argument_test.c"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -862,7 +974,9 @@
     "name": "json_rewrite", 
     "src": [
       "test/core/json/json_rewrite.c"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -876,7 +990,9 @@
     "name": "json_rewrite_test", 
     "src": [
       "test/core/json/json_rewrite_test.c"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -890,7 +1006,9 @@
     "name": "json_stream_error_test", 
     "src": [
       "test/core/json/json_stream_error_test.c"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -904,7 +1022,9 @@
     "name": "json_test", 
     "src": [
       "test/core/json/json_test.c"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -918,7 +1038,9 @@
     "name": "lame_client_test", 
     "src": [
       "test/core/surface/lame_client_test.c"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -932,7 +1054,9 @@
     "name": "lb_policies_test", 
     "src": [
       "test/core/client_config/lb_policies_test.c"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -946,7 +1070,9 @@
     "name": "low_level_ping_pong_benchmark", 
     "src": [
       "test/core/network_benchmarks/low_level_ping_pong.c"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -960,7 +1086,25 @@
     "name": "message_compress_test", 
     "src": [
       "test/core/compression/message_compress_test.c"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
+  }, 
+  {
+    "deps": [
+      "gpr", 
+      "gpr_test_util", 
+      "grpc", 
+      "grpc_test_util"
+    ], 
+    "headers": [], 
+    "language": "c", 
+    "name": "mlog_test", 
+    "src": [
+      "test/core/census/mlog_test.c"
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -974,7 +1118,9 @@
     "name": "multiple_server_queues_test", 
     "src": [
       "test/core/end2end/multiple_server_queues_test.c"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -986,7 +1132,9 @@
     "name": "murmur_hash_test", 
     "src": [
       "test/core/support/murmur_hash_test.c"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -1000,7 +1148,9 @@
     "name": "no_server_test", 
     "src": [
       "test/core/end2end/no_server_test.c"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -1014,7 +1164,9 @@
     "name": "resolve_address_test", 
     "src": [
       "test/core/iomgr/resolve_address_test.c"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -1028,7 +1180,9 @@
     "name": "secure_channel_create_test", 
     "src": [
       "test/core/surface/secure_channel_create_test.c"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -1042,7 +1196,9 @@
     "name": "secure_endpoint_test", 
     "src": [
       "test/core/security/secure_endpoint_test.c"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -1056,7 +1212,9 @@
     "name": "server_chttp2_test", 
     "src": [
       "test/core/surface/server_chttp2_test.c"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -1070,7 +1228,9 @@
     "name": "server_test", 
     "src": [
       "test/core/surface/server_test.c"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -1085,7 +1245,9 @@
     "name": "set_initial_connect_string_test", 
     "src": [
       "test/core/client_config/set_initial_connect_string_test.c"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -1099,7 +1261,9 @@
     "name": "sockaddr_resolver_test", 
     "src": [
       "test/core/client_config/resolvers/sockaddr_resolver_test.c"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -1113,7 +1277,9 @@
     "name": "sockaddr_utils_test", 
     "src": [
       "test/core/iomgr/sockaddr_utils_test.c"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -1127,7 +1293,9 @@
     "name": "socket_utils_test", 
     "src": [
       "test/core/iomgr/socket_utils_test.c"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -1141,7 +1309,9 @@
     "name": "tcp_client_posix_test", 
     "src": [
       "test/core/iomgr/tcp_client_posix_test.c"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -1155,7 +1325,9 @@
     "name": "tcp_posix_test", 
     "src": [
       "test/core/iomgr/tcp_posix_test.c"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -1169,7 +1341,9 @@
     "name": "tcp_server_posix_test", 
     "src": [
       "test/core/iomgr/tcp_server_posix_test.c"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -1183,7 +1357,9 @@
     "name": "time_averaged_stats_test", 
     "src": [
       "test/core/iomgr/time_averaged_stats_test.c"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -1197,7 +1373,9 @@
     "name": "timeout_encoding_test", 
     "src": [
       "test/core/transport/chttp2/timeout_encoding_test.c"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -1211,7 +1389,9 @@
     "name": "timer_heap_test", 
     "src": [
       "test/core/iomgr/timer_heap_test.c"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -1225,7 +1405,9 @@
     "name": "timer_list_test", 
     "src": [
       "test/core/iomgr/timer_list_test.c"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -1239,7 +1421,9 @@
     "name": "timers_test", 
     "src": [
       "test/core/profiling/timers_test.c"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -1253,7 +1437,9 @@
     "name": "transport_connectivity_state_test", 
     "src": [
       "test/core/transport/connectivity_state_test.c"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -1267,7 +1453,9 @@
     "name": "transport_metadata_test", 
     "src": [
       "test/core/transport/metadata_test.c"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -1281,7 +1469,9 @@
     "name": "transport_security_test", 
     "src": [
       "test/core/tsi/transport_security_test.c"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -1295,7 +1485,9 @@
     "name": "udp_server_test", 
     "src": [
       "test/core/iomgr/udp_server_test.c"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -1309,7 +1501,9 @@
     "name": "uri_parser_test", 
     "src": [
       "test/core/client_config/uri_parser_test.c"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -1323,7 +1517,9 @@
     "name": "workqueue_test", 
     "src": [
       "test/core/iomgr/workqueue_test.c"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -1339,7 +1535,9 @@
     "name": "alarm_cpp_test", 
     "src": [
       "test/cpp/common/alarm_cpp_test.cc"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -1355,7 +1553,9 @@
     "name": "async_end2end_test", 
     "src": [
       "test/cpp/end2end/async_end2end_test.cc"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -1372,7 +1572,9 @@
     "name": "async_streaming_ping_pong_test", 
     "src": [
       "test/cpp/qps/async_streaming_ping_pong_test.cc"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -1389,7 +1591,9 @@
     "name": "async_unary_ping_pong_test", 
     "src": [
       "test/cpp/qps/async_unary_ping_pong_test.cc"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -1405,7 +1609,9 @@
     "name": "auth_property_iterator_test", 
     "src": [
       "test/cpp/common/auth_property_iterator_test.cc"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -1418,7 +1624,9 @@
     "name": "channel_arguments_test", 
     "src": [
       "test/cpp/common/channel_arguments_test.cc"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -1434,7 +1642,9 @@
     "name": "cli_call_test", 
     "src": [
       "test/cpp/util/cli_call_test.cc"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -1450,7 +1660,9 @@
     "name": "client_crash_test", 
     "src": [
       "test/cpp/end2end/client_crash_test.cc"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -1466,7 +1678,9 @@
     "name": "client_crash_test_server", 
     "src": [
       "test/cpp/end2end/client_crash_test_server.cc"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -1479,7 +1693,9 @@
     "name": "credentials_test", 
     "src": [
       "test/cpp/client/credentials_test.cc"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -1494,7 +1710,9 @@
     "name": "cxx_byte_buffer_test", 
     "src": [
       "test/cpp/util/byte_buffer_test.cc"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -1509,7 +1727,9 @@
     "name": "cxx_slice_test", 
     "src": [
       "test/cpp/util/slice_test.cc"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -1520,7 +1740,9 @@
     "name": "cxx_string_ref_test", 
     "src": [
       "test/cpp/util/string_ref_test.cc"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -1535,7 +1757,9 @@
     "name": "cxx_time_test", 
     "src": [
       "test/cpp/util/time_test.cc"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -1551,7 +1775,9 @@
     "name": "end2end_test", 
     "src": [
       "test/cpp/end2end/end2end_test.cc"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -1568,7 +1794,9 @@
     "name": "generic_async_streaming_ping_pong_test", 
     "src": [
       "test/cpp/qps/generic_async_streaming_ping_pong_test.cc"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -1584,7 +1812,9 @@
     "name": "generic_end2end_test", 
     "src": [
       "test/cpp/end2end/generic_end2end_test.cc"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -1601,7 +1831,9 @@
     "name": "grpc_cli", 
     "src": [
       "test/cpp/util/grpc_cli.cc"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -1612,7 +1844,9 @@
     "name": "grpc_cpp_plugin", 
     "src": [
       "src/compiler/cpp_plugin.cc"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -1623,7 +1857,9 @@
     "name": "grpc_csharp_plugin", 
     "src": [
       "src/compiler/csharp_plugin.cc"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -1634,7 +1870,9 @@
     "name": "grpc_objective_c_plugin", 
     "src": [
       "src/compiler/objective_c_plugin.cc"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -1645,7 +1883,9 @@
     "name": "grpc_python_plugin", 
     "src": [
       "src/compiler/python_plugin.cc"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -1656,7 +1896,28 @@
     "name": "grpc_ruby_plugin", 
     "src": [
       "src/compiler/ruby_plugin.cc"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
+  }, 
+  {
+    "deps": [
+      "grpc", 
+      "grpc++", 
+      "grpc++_test_util", 
+      "grpc_test_util"
+    ], 
+    "headers": [
+      "src/proto/grpc/lb/v0/load_balancer.grpc.pb.h", 
+      "src/proto/grpc/lb/v0/load_balancer.pb.h"
+    ], 
+    "language": "c++", 
+    "name": "grpclb_api_test", 
+    "src": [
+      "test/cpp/grpclb/grpclb_api_test.cc"
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -1672,7 +1933,9 @@
     "name": "hybrid_end2end_test", 
     "src": [
       "test/cpp/end2end/hybrid_end2end_test.cc"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -1689,7 +1952,9 @@
     "headers": [], 
     "language": "c++", 
     "name": "interop_client", 
-    "src": []
+    "src": [], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -1706,7 +1971,9 @@
     "headers": [], 
     "language": "c++", 
     "name": "interop_server", 
-    "src": []
+    "src": [], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -1720,7 +1987,9 @@
     "name": "interop_test", 
     "src": [
       "test/cpp/interop/interop_test.cc"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -1739,7 +2008,9 @@
     "src": [
       "test/cpp/interop/metrics_client.cc", 
       "test/cpp/util/metrics_server.h"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -1755,7 +2026,9 @@
     "name": "mock_test", 
     "src": [
       "test/cpp/end2end/mock_test.cc"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -1773,7 +2046,9 @@
     "name": "qps_driver", 
     "src": [
       "test/cpp/qps/qps_driver.cc"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -1790,7 +2065,9 @@
     "name": "qps_interarrival_test", 
     "src": [
       "test/cpp/qps/qps_interarrival_test.cc"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -1808,7 +2085,9 @@
     "name": "qps_openloop_test", 
     "src": [
       "test/cpp/qps/qps_openloop_test.cc"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -1826,7 +2105,9 @@
     "name": "qps_test", 
     "src": [
       "test/cpp/qps/qps_test.cc"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -1849,7 +2130,9 @@
       "test/cpp/qps/client.h", 
       "test/cpp/qps/server.h", 
       "test/cpp/qps/worker.cc"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -1873,7 +2156,9 @@
     "name": "reconnect_interop_client", 
     "src": [
       "test/cpp/interop/reconnect_interop_client.cc"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -1899,7 +2184,9 @@
     "name": "reconnect_interop_server", 
     "src": [
       "test/cpp/interop/reconnect_interop_server.cc"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -1915,7 +2202,9 @@
     "name": "secure_auth_context_test", 
     "src": [
       "test/cpp/common/secure_auth_context_test.cc"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -1932,7 +2221,9 @@
     "name": "secure_sync_unary_ping_pong_test", 
     "src": [
       "test/cpp/qps/secure_sync_unary_ping_pong_test.cc"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -1948,7 +2239,9 @@
     "name": "server_crash_test", 
     "src": [
       "test/cpp/end2end/server_crash_test.cc"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -1964,7 +2257,9 @@
     "name": "server_crash_test_client", 
     "src": [
       "test/cpp/end2end/server_crash_test_client.cc"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -1980,7 +2275,9 @@
     "name": "shutdown_test", 
     "src": [
       "test/cpp/end2end/shutdown_test.cc"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -1995,7 +2292,9 @@
     "name": "status_test", 
     "src": [
       "test/cpp/util/status_test.cc"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -2011,7 +2310,9 @@
     "name": "streaming_throughput_test", 
     "src": [
       "test/cpp/end2end/streaming_throughput_test.cc"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -2048,7 +2349,9 @@
       "test/cpp/interop/stress_test.cc", 
       "test/cpp/util/metrics_server.cc", 
       "test/cpp/util/metrics_server.h"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -2065,7 +2368,9 @@
     "name": "sync_streaming_ping_pong_test", 
     "src": [
       "test/cpp/qps/sync_streaming_ping_pong_test.cc"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -2082,7 +2387,9 @@
     "name": "sync_unary_ping_pong_test", 
     "src": [
       "test/cpp/qps/sync_unary_ping_pong_test.cc"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -2098,7 +2405,9 @@
     "name": "thread_stress_test", 
     "src": [
       "test/cpp/end2end/thread_stress_test.cc"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -2118,7 +2427,9 @@
     "name": "zookeeper_test", 
     "src": [
       "test/cpp/end2end/zookeeper_test.cc"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -2130,7 +2441,477 @@
     "name": "public_headers_must_be_c89", 
     "src": [
       "test/core/surface/public_headers_must_be_c89.c"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
+  }, 
+  {
+    "deps": [
+      "boringssl", 
+      "boringssl_aes_test_lib", 
+      "boringssl_test_util"
+    ], 
+    "headers": [], 
+    "language": "c++", 
+    "name": "boringssl_aes_test", 
+    "src": [], 
+    "third_party": true, 
+    "type": "target"
+  }, 
+  {
+    "deps": [
+      "boringssl", 
+      "boringssl_base64_test_lib", 
+      "boringssl_test_util"
+    ], 
+    "headers": [], 
+    "language": "c++", 
+    "name": "boringssl_base64_test", 
+    "src": [], 
+    "third_party": true, 
+    "type": "target"
+  }, 
+  {
+    "deps": [
+      "boringssl", 
+      "boringssl_bio_test_lib", 
+      "boringssl_test_util"
+    ], 
+    "headers": [], 
+    "language": "c++", 
+    "name": "boringssl_bio_test", 
+    "src": [], 
+    "third_party": true, 
+    "type": "target"
+  }, 
+  {
+    "deps": [
+      "boringssl", 
+      "boringssl_bn_test_lib", 
+      "boringssl_test_util"
+    ], 
+    "headers": [], 
+    "language": "c++", 
+    "name": "boringssl_bn_test", 
+    "src": [], 
+    "third_party": true, 
+    "type": "target"
+  }, 
+  {
+    "deps": [
+      "boringssl", 
+      "boringssl_bytestring_test_lib", 
+      "boringssl_test_util"
+    ], 
+    "headers": [], 
+    "language": "c++", 
+    "name": "boringssl_bytestring_test", 
+    "src": [], 
+    "third_party": true, 
+    "type": "target"
+  }, 
+  {
+    "deps": [
+      "boringssl", 
+      "boringssl_aead_test_lib", 
+      "boringssl_test_util"
+    ], 
+    "headers": [], 
+    "language": "c++", 
+    "name": "boringssl_aead_test", 
+    "src": [], 
+    "third_party": true, 
+    "type": "target"
+  }, 
+  {
+    "deps": [
+      "boringssl", 
+      "boringssl_cipher_test_lib", 
+      "boringssl_test_util"
+    ], 
+    "headers": [], 
+    "language": "c++", 
+    "name": "boringssl_cipher_test", 
+    "src": [], 
+    "third_party": true, 
+    "type": "target"
+  }, 
+  {
+    "deps": [
+      "boringssl", 
+      "boringssl_cmac_test_lib", 
+      "boringssl_test_util"
+    ], 
+    "headers": [], 
+    "language": "c++", 
+    "name": "boringssl_cmac_test", 
+    "src": [], 
+    "third_party": true, 
+    "type": "target"
+  }, 
+  {
+    "deps": [
+      "boringssl", 
+      "boringssl_constant_time_test_lib", 
+      "boringssl_test_util"
+    ], 
+    "headers": [], 
+    "language": "c++", 
+    "name": "boringssl_constant_time_test", 
+    "src": [], 
+    "third_party": true, 
+    "type": "target"
+  }, 
+  {
+    "deps": [
+      "boringssl", 
+      "boringssl_ed25519_test_lib", 
+      "boringssl_test_util"
+    ], 
+    "headers": [], 
+    "language": "c++", 
+    "name": "boringssl_ed25519_test", 
+    "src": [], 
+    "third_party": true, 
+    "type": "target"
+  }, 
+  {
+    "deps": [
+      "boringssl", 
+      "boringssl_test_util", 
+      "boringssl_x25519_test_lib"
+    ], 
+    "headers": [], 
+    "language": "c++", 
+    "name": "boringssl_x25519_test", 
+    "src": [], 
+    "third_party": true, 
+    "type": "target"
+  }, 
+  {
+    "deps": [
+      "boringssl", 
+      "boringssl_dh_test_lib", 
+      "boringssl_test_util"
+    ], 
+    "headers": [], 
+    "language": "c++", 
+    "name": "boringssl_dh_test", 
+    "src": [], 
+    "third_party": true, 
+    "type": "target"
+  }, 
+  {
+    "deps": [
+      "boringssl", 
+      "boringssl_digest_test_lib", 
+      "boringssl_test_util"
+    ], 
+    "headers": [], 
+    "language": "c++", 
+    "name": "boringssl_digest_test", 
+    "src": [], 
+    "third_party": true, 
+    "type": "target"
+  }, 
+  {
+    "deps": [
+      "boringssl", 
+      "boringssl_dsa_test_lib", 
+      "boringssl_test_util"
+    ], 
+    "headers": [], 
+    "language": "c++", 
+    "name": "boringssl_dsa_test", 
+    "src": [], 
+    "third_party": true, 
+    "type": "target"
+  }, 
+  {
+    "deps": [
+      "boringssl", 
+      "boringssl_ec_test_lib", 
+      "boringssl_test_util"
+    ], 
+    "headers": [], 
+    "language": "c++", 
+    "name": "boringssl_ec_test", 
+    "src": [], 
+    "third_party": true, 
+    "type": "target"
+  }, 
+  {
+    "deps": [
+      "boringssl", 
+      "boringssl_example_mul_lib", 
+      "boringssl_test_util"
+    ], 
+    "headers": [], 
+    "language": "c++", 
+    "name": "boringssl_example_mul", 
+    "src": [], 
+    "third_party": true, 
+    "type": "target"
+  }, 
+  {
+    "deps": [
+      "boringssl", 
+      "boringssl_ecdsa_test_lib", 
+      "boringssl_test_util"
+    ], 
+    "headers": [], 
+    "language": "c++", 
+    "name": "boringssl_ecdsa_test", 
+    "src": [], 
+    "third_party": true, 
+    "type": "target"
+  }, 
+  {
+    "deps": [
+      "boringssl", 
+      "boringssl_err_test_lib", 
+      "boringssl_test_util"
+    ], 
+    "headers": [], 
+    "language": "c++", 
+    "name": "boringssl_err_test", 
+    "src": [], 
+    "third_party": true, 
+    "type": "target"
+  }, 
+  {
+    "deps": [
+      "boringssl", 
+      "boringssl_evp_extra_test_lib", 
+      "boringssl_test_util"
+    ], 
+    "headers": [], 
+    "language": "c++", 
+    "name": "boringssl_evp_extra_test", 
+    "src": [], 
+    "third_party": true, 
+    "type": "target"
+  }, 
+  {
+    "deps": [
+      "boringssl", 
+      "boringssl_evp_test_lib", 
+      "boringssl_test_util"
+    ], 
+    "headers": [], 
+    "language": "c++", 
+    "name": "boringssl_evp_test", 
+    "src": [], 
+    "third_party": true, 
+    "type": "target"
+  }, 
+  {
+    "deps": [
+      "boringssl", 
+      "boringssl_pbkdf_test_lib", 
+      "boringssl_test_util"
+    ], 
+    "headers": [], 
+    "language": "c++", 
+    "name": "boringssl_pbkdf_test", 
+    "src": [], 
+    "third_party": true, 
+    "type": "target"
+  }, 
+  {
+    "deps": [
+      "boringssl", 
+      "boringssl_hkdf_test_lib", 
+      "boringssl_test_util"
+    ], 
+    "headers": [], 
+    "language": "c++", 
+    "name": "boringssl_hkdf_test", 
+    "src": [], 
+    "third_party": true, 
+    "type": "target"
+  }, 
+  {
+    "deps": [
+      "boringssl", 
+      "boringssl_hmac_test_lib", 
+      "boringssl_test_util"
+    ], 
+    "headers": [], 
+    "language": "c++", 
+    "name": "boringssl_hmac_test", 
+    "src": [], 
+    "third_party": true, 
+    "type": "target"
+  }, 
+  {
+    "deps": [
+      "boringssl", 
+      "boringssl_lhash_test_lib", 
+      "boringssl_test_util"
+    ], 
+    "headers": [], 
+    "language": "c++", 
+    "name": "boringssl_lhash_test", 
+    "src": [], 
+    "third_party": true, 
+    "type": "target"
+  }, 
+  {
+    "deps": [
+      "boringssl", 
+      "boringssl_gcm_test_lib", 
+      "boringssl_test_util"
+    ], 
+    "headers": [], 
+    "language": "c++", 
+    "name": "boringssl_gcm_test", 
+    "src": [], 
+    "third_party": true, 
+    "type": "target"
+  }, 
+  {
+    "deps": [
+      "boringssl", 
+      "boringssl_pkcs12_test_lib", 
+      "boringssl_test_util"
+    ], 
+    "headers": [], 
+    "language": "c++", 
+    "name": "boringssl_pkcs12_test", 
+    "src": [], 
+    "third_party": true, 
+    "type": "target"
+  }, 
+  {
+    "deps": [
+      "boringssl", 
+      "boringssl_pkcs8_test_lib", 
+      "boringssl_test_util"
+    ], 
+    "headers": [], 
+    "language": "c++", 
+    "name": "boringssl_pkcs8_test", 
+    "src": [], 
+    "third_party": true, 
+    "type": "target"
+  }, 
+  {
+    "deps": [
+      "boringssl", 
+      "boringssl_poly1305_test_lib", 
+      "boringssl_test_util"
+    ], 
+    "headers": [], 
+    "language": "c++", 
+    "name": "boringssl_poly1305_test", 
+    "src": [], 
+    "third_party": true, 
+    "type": "target"
+  }, 
+  {
+    "deps": [
+      "boringssl", 
+      "boringssl_refcount_test_lib", 
+      "boringssl_test_util"
+    ], 
+    "headers": [], 
+    "language": "c++", 
+    "name": "boringssl_refcount_test", 
+    "src": [], 
+    "third_party": true, 
+    "type": "target"
+  }, 
+  {
+    "deps": [
+      "boringssl", 
+      "boringssl_rsa_test_lib", 
+      "boringssl_test_util"
+    ], 
+    "headers": [], 
+    "language": "c++", 
+    "name": "boringssl_rsa_test", 
+    "src": [], 
+    "third_party": true, 
+    "type": "target"
+  }, 
+  {
+    "deps": [
+      "boringssl", 
+      "boringssl_test_util", 
+      "boringssl_thread_test_lib"
+    ], 
+    "headers": [], 
+    "language": "c++", 
+    "name": "boringssl_thread_test", 
+    "src": [], 
+    "third_party": true, 
+    "type": "target"
+  }, 
+  {
+    "deps": [
+      "boringssl", 
+      "boringssl_pkcs7_test_lib", 
+      "boringssl_test_util"
+    ], 
+    "headers": [], 
+    "language": "c++", 
+    "name": "boringssl_pkcs7_test", 
+    "src": [], 
+    "third_party": true, 
+    "type": "target"
+  }, 
+  {
+    "deps": [
+      "boringssl", 
+      "boringssl_tab_test_lib", 
+      "boringssl_test_util"
+    ], 
+    "headers": [], 
+    "language": "c++", 
+    "name": "boringssl_tab_test", 
+    "src": [], 
+    "third_party": true, 
+    "type": "target"
+  }, 
+  {
+    "deps": [
+      "boringssl", 
+      "boringssl_test_util", 
+      "boringssl_v3name_test_lib"
+    ], 
+    "headers": [], 
+    "language": "c++", 
+    "name": "boringssl_v3name_test", 
+    "src": [], 
+    "third_party": true, 
+    "type": "target"
+  }, 
+  {
+    "deps": [
+      "boringssl", 
+      "boringssl_pqueue_test_lib", 
+      "boringssl_test_util"
+    ], 
+    "headers": [], 
+    "language": "c++", 
+    "name": "boringssl_pqueue_test", 
+    "src": [], 
+    "third_party": true, 
+    "type": "target"
+  }, 
+  {
+    "deps": [
+      "boringssl", 
+      "boringssl_ssl_test_lib", 
+      "boringssl_test_util"
+    ], 
+    "headers": [], 
+    "language": "c++", 
+    "name": "boringssl_ssl_test", 
+    "src": [], 
+    "third_party": true, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -2145,7 +2926,9 @@
     "name": "badreq_bad_client_test", 
     "src": [
       "test/core/bad_client/tests/badreq.c"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -2160,7 +2943,9 @@
     "name": "connection_prefix_bad_client_test", 
     "src": [
       "test/core/bad_client/tests/connection_prefix.c"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -2175,7 +2960,9 @@
     "name": "headers_bad_client_test", 
     "src": [
       "test/core/bad_client/tests/headers.c"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -2190,7 +2977,9 @@
     "name": "initial_settings_frame_bad_client_test", 
     "src": [
       "test/core/bad_client/tests/initial_settings_frame.c"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -2205,7 +2994,9 @@
     "name": "server_registered_method_bad_client_test", 
     "src": [
       "test/core/bad_client/tests/server_registered_method.c"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -2220,7 +3011,9 @@
     "name": "simple_request_bad_client_test", 
     "src": [
       "test/core/bad_client/tests/simple_request.c"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -2235,7 +3028,9 @@
     "name": "unknown_frame_bad_client_test", 
     "src": [
       "test/core/bad_client/tests/unknown_frame.c"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -2250,7 +3045,9 @@
     "name": "window_overflow_bad_client_test", 
     "src": [
       "test/core/bad_client/tests/window_overflow.c"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -2265,7 +3062,9 @@
     "name": "bad_ssl_alpn_server", 
     "src": [
       "test/core/bad_ssl/servers/alpn.c"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -2280,7 +3079,9 @@
     "name": "bad_ssl_cert_server", 
     "src": [
       "test/core/bad_ssl/servers/cert.c"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -2294,7 +3095,9 @@
     "name": "bad_ssl_alpn_test", 
     "src": [
       "test/core/bad_ssl/bad_ssl_test.c"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -2308,7 +3111,9 @@
     "name": "bad_ssl_cert_test", 
     "src": [
       "test/core/bad_ssl/bad_ssl_test.c"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -2324,7 +3129,9 @@
     "name": "h2_census_test", 
     "src": [
       "test/core/end2end/fixtures/h2_census.c"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -2340,7 +3147,9 @@
     "name": "h2_compress_test", 
     "src": [
       "test/core/end2end/fixtures/h2_compress.c"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -2356,7 +3165,9 @@
     "name": "h2_fakesec_test", 
     "src": [
       "test/core/end2end/fixtures/h2_fakesec.c"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -2372,7 +3183,9 @@
     "name": "h2_full_test", 
     "src": [
       "test/core/end2end/fixtures/h2_full.c"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -2388,7 +3201,9 @@
     "name": "h2_full+pipe_test", 
     "src": [
       "test/core/end2end/fixtures/h2_full+pipe.c"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -2404,7 +3219,9 @@
     "name": "h2_full+poll_test", 
     "src": [
       "test/core/end2end/fixtures/h2_full+poll.c"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -2420,7 +3237,9 @@
     "name": "h2_full+poll+pipe_test", 
     "src": [
       "test/core/end2end/fixtures/h2_full+poll+pipe.c"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -2436,7 +3255,9 @@
     "name": "h2_oauth2_test", 
     "src": [
       "test/core/end2end/fixtures/h2_oauth2.c"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -2452,7 +3273,9 @@
     "name": "h2_proxy_test", 
     "src": [
       "test/core/end2end/fixtures/h2_proxy.c"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -2468,7 +3291,9 @@
     "name": "h2_sockpair_test", 
     "src": [
       "test/core/end2end/fixtures/h2_sockpair.c"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -2484,7 +3309,9 @@
     "name": "h2_sockpair+trace_test", 
     "src": [
       "test/core/end2end/fixtures/h2_sockpair+trace.c"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -2500,7 +3327,9 @@
     "name": "h2_sockpair_1byte_test", 
     "src": [
       "test/core/end2end/fixtures/h2_sockpair_1byte.c"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -2516,7 +3345,9 @@
     "name": "h2_ssl_test", 
     "src": [
       "test/core/end2end/fixtures/h2_ssl.c"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -2532,7 +3363,9 @@
     "name": "h2_ssl+poll_test", 
     "src": [
       "test/core/end2end/fixtures/h2_ssl+poll.c"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -2548,7 +3381,9 @@
     "name": "h2_ssl_proxy_test", 
     "src": [
       "test/core/end2end/fixtures/h2_ssl_proxy.c"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -2564,7 +3399,9 @@
     "name": "h2_uchannel_test", 
     "src": [
       "test/core/end2end/fixtures/h2_uchannel.c"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -2580,7 +3417,9 @@
     "name": "h2_uds_test", 
     "src": [
       "test/core/end2end/fixtures/h2_uds.c"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -2596,7 +3435,9 @@
     "name": "h2_uds+poll_test", 
     "src": [
       "test/core/end2end/fixtures/h2_uds+poll.c"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -2611,7 +3452,9 @@
     "name": "h2_census_nosec_test", 
     "src": [
       "test/core/end2end/fixtures/h2_census.c"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -2626,7 +3469,9 @@
     "name": "h2_compress_nosec_test", 
     "src": [
       "test/core/end2end/fixtures/h2_compress.c"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -2641,7 +3486,9 @@
     "name": "h2_full_nosec_test", 
     "src": [
       "test/core/end2end/fixtures/h2_full.c"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -2656,7 +3503,9 @@
     "name": "h2_full+pipe_nosec_test", 
     "src": [
       "test/core/end2end/fixtures/h2_full+pipe.c"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -2671,7 +3520,9 @@
     "name": "h2_full+poll_nosec_test", 
     "src": [
       "test/core/end2end/fixtures/h2_full+poll.c"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -2686,7 +3537,9 @@
     "name": "h2_full+poll+pipe_nosec_test", 
     "src": [
       "test/core/end2end/fixtures/h2_full+poll+pipe.c"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -2701,7 +3554,9 @@
     "name": "h2_proxy_nosec_test", 
     "src": [
       "test/core/end2end/fixtures/h2_proxy.c"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -2716,7 +3571,9 @@
     "name": "h2_sockpair_nosec_test", 
     "src": [
       "test/core/end2end/fixtures/h2_sockpair.c"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -2731,7 +3588,9 @@
     "name": "h2_sockpair+trace_nosec_test", 
     "src": [
       "test/core/end2end/fixtures/h2_sockpair+trace.c"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -2746,7 +3605,9 @@
     "name": "h2_sockpair_1byte_nosec_test", 
     "src": [
       "test/core/end2end/fixtures/h2_sockpair_1byte.c"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -2761,7 +3622,9 @@
     "name": "h2_uchannel_nosec_test", 
     "src": [
       "test/core/end2end/fixtures/h2_uchannel.c"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -2776,7 +3639,9 @@
     "name": "h2_uds_nosec_test", 
     "src": [
       "test/core/end2end/fixtures/h2_uds.c"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [
@@ -2791,7 +3656,9 @@
     "name": "h2_uds+poll_nosec_test", 
     "src": [
       "test/core/end2end/fixtures/h2_uds+poll.c"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "target"
   }, 
   {
     "deps": [], 
@@ -2841,13 +3708,14 @@
       "src/core/profiling/timers.h", 
       "src/core/support/block_annotate.h", 
       "src/core/support/env.h", 
-      "src/core/support/file.h", 
+      "src/core/support/load_file.h", 
       "src/core/support/murmur_hash.h", 
       "src/core/support/stack_lockfree.h", 
       "src/core/support/string.h", 
       "src/core/support/string_win32.h", 
       "src/core/support/thd_internal.h", 
-      "src/core/support/time_precise.h"
+      "src/core/support/time_precise.h", 
+      "src/core/support/tmpfile.h"
     ], 
     "language": "c", 
     "name": "gpr", 
@@ -2909,12 +3777,10 @@
       "src/core/support/env_linux.c", 
       "src/core/support/env_posix.c", 
       "src/core/support/env_win32.c", 
-      "src/core/support/file.c", 
-      "src/core/support/file.h", 
-      "src/core/support/file_posix.c", 
-      "src/core/support/file_win32.c", 
       "src/core/support/histogram.c", 
       "src/core/support/host_port.c", 
+      "src/core/support/load_file.c", 
+      "src/core/support/load_file.h", 
       "src/core/support/log.c", 
       "src/core/support/log_android.c", 
       "src/core/support/log_linux.c", 
@@ -2946,8 +3812,13 @@
       "src/core/support/time_precise.h", 
       "src/core/support/time_win32.c", 
       "src/core/support/tls_pthread.c", 
+      "src/core/support/tmpfile.h", 
+      "src/core/support/tmpfile_posix.c", 
+      "src/core/support/tmpfile_win32.c", 
       "src/core/support/wrap_memcpy.c"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "lib"
   }, 
   {
     "deps": [
@@ -2961,7 +3832,9 @@
     "src": [
       "test/core/util/test_config.c", 
       "test/core/util/test_config.h"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "lib"
   }, 
   {
     "deps": [
@@ -2978,7 +3851,7 @@
       "include/grpc/status.h", 
       "src/core/census/aggregation.h", 
       "src/core/census/grpc_filter.h", 
-      "src/core/census/log.h", 
+      "src/core/census/mlog.h", 
       "src/core/census/rpc_metric_id.h", 
       "src/core/channel/channel_args.h", 
       "src/core/channel/channel_stack.h", 
@@ -2993,6 +3866,7 @@
       "src/core/client_config/client_config.h", 
       "src/core/client_config/connector.h", 
       "src/core/client_config/initial_connect_string.h", 
+      "src/core/client_config/lb_policies/load_balancer_api.h", 
       "src/core/client_config/lb_policies/pick_first.h", 
       "src/core/client_config/lb_policies/round_robin.h", 
       "src/core/client_config/lb_policy.h", 
@@ -3043,7 +3917,6 @@
       "src/core/iomgr/time_averaged_stats.h", 
       "src/core/iomgr/timer.h", 
       "src/core/iomgr/timer_heap.h", 
-      "src/core/iomgr/timer_internal.h", 
       "src/core/iomgr/udp_server.h", 
       "src/core/iomgr/wakeup_fd_pipe.h", 
       "src/core/iomgr/wakeup_fd_posix.h", 
@@ -3054,8 +3927,9 @@
       "src/core/json/json_common.h", 
       "src/core/json/json_reader.h", 
       "src/core/json/json_writer.h", 
+      "src/core/proto/grpc/lb/v0/load_balancer.pb.h", 
       "src/core/security/auth_filters.h", 
-      "src/core/security/base64.h", 
+      "src/core/security/b64.h", 
       "src/core/security/credentials.h", 
       "src/core/security/handshake.h", 
       "src/core/security/json_token.h", 
@@ -3106,7 +3980,11 @@
       "src/core/tsi/ssl_transport_security.h", 
       "src/core/tsi/ssl_types.h", 
       "src/core/tsi/transport_security.h", 
-      "src/core/tsi/transport_security_interface.h"
+      "src/core/tsi/transport_security_interface.h", 
+      "third_party/nanopb/pb.h", 
+      "third_party/nanopb/pb_common.h", 
+      "third_party/nanopb/pb_decode.h", 
+      "third_party/nanopb/pb_encode.h"
     ], 
     "language": "c", 
     "name": "grpc", 
@@ -3124,8 +4002,8 @@
       "src/core/census/grpc_filter.c", 
       "src/core/census/grpc_filter.h", 
       "src/core/census/initialize.c", 
-      "src/core/census/log.c", 
-      "src/core/census/log.h", 
+      "src/core/census/mlog.c", 
+      "src/core/census/mlog.h", 
       "src/core/census/operation.c", 
       "src/core/census/placeholders.c", 
       "src/core/census/rpc_metric_id.h", 
@@ -3156,6 +4034,8 @@
       "src/core/client_config/default_initial_connect_string.c", 
       "src/core/client_config/initial_connect_string.c", 
       "src/core/client_config/initial_connect_string.h", 
+      "src/core/client_config/lb_policies/load_balancer_api.c", 
+      "src/core/client_config/lb_policies/load_balancer_api.h", 
       "src/core/client_config/lb_policies/pick_first.c", 
       "src/core/client_config/lb_policies/pick_first.h", 
       "src/core/client_config/lb_policies/round_robin.c", 
@@ -3184,8 +4064,8 @@
       "src/core/client_config/subchannel_index.h", 
       "src/core/client_config/uri_parser.c", 
       "src/core/client_config/uri_parser.h", 
-      "src/core/compression/algorithm.c", 
       "src/core/compression/algorithm_metadata.h", 
+      "src/core/compression/compression_algorithm.c", 
       "src/core/compression/message_compress.c", 
       "src/core/compression/message_compress.h", 
       "src/core/debug/trace.c", 
@@ -3260,7 +4140,6 @@
       "src/core/iomgr/timer.h", 
       "src/core/iomgr/timer_heap.c", 
       "src/core/iomgr/timer_heap.h", 
-      "src/core/iomgr/timer_internal.h", 
       "src/core/iomgr/udp_server.c", 
       "src/core/iomgr/udp_server.h", 
       "src/core/iomgr/wakeup_fd_eventfd.c", 
@@ -3282,9 +4161,11 @@
       "src/core/json/json_string.c", 
       "src/core/json/json_writer.c", 
       "src/core/json/json_writer.h", 
+      "src/core/proto/grpc/lb/v0/load_balancer.pb.c", 
+      "src/core/proto/grpc/lb/v0/load_balancer.pb.h", 
       "src/core/security/auth_filters.h", 
-      "src/core/security/base64.c", 
-      "src/core/security/base64.h", 
+      "src/core/security/b64.c", 
+      "src/core/security/b64.h", 
       "src/core/security/client_auth_filter.c", 
       "src/core/security/credentials.c", 
       "src/core/security/credentials.h", 
@@ -3404,7 +4285,9 @@
       "src/core/tsi/transport_security.c", 
       "src/core/tsi/transport_security.h", 
       "src/core/tsi/transport_security_interface.h"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "lib"
   }, 
   {
     "deps": [], 
@@ -3453,7 +4336,21 @@
       "include/grpc/impl/codegen/sync_posix.h", 
       "include/grpc/impl/codegen/sync_win32.h", 
       "include/grpc/impl/codegen/time.h"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "lib"
+  }, 
+  {
+    "deps": [
+      "gpr", 
+      "grpc"
+    ], 
+    "headers": [], 
+    "language": "c", 
+    "name": "grpc_dll", 
+    "src": [], 
+    "third_party": false, 
+    "type": "lib"
   }, 
   {
     "deps": [
@@ -3496,7 +4393,9 @@
       "test/core/util/port_windows.c", 
       "test/core/util/slice_splitter.c", 
       "test/core/util/slice_splitter.h"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "lib"
   }, 
   {
     "deps": [
@@ -3531,7 +4430,9 @@
       "test/core/util/port_windows.c", 
       "test/core/util/slice_splitter.c", 
       "test/core/util/slice_splitter.h"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "lib"
   }, 
   {
     "deps": [
@@ -3547,7 +4448,7 @@
       "include/grpc/status.h", 
       "src/core/census/aggregation.h", 
       "src/core/census/grpc_filter.h", 
-      "src/core/census/log.h", 
+      "src/core/census/mlog.h", 
       "src/core/census/rpc_metric_id.h", 
       "src/core/channel/channel_args.h", 
       "src/core/channel/channel_stack.h", 
@@ -3562,6 +4463,7 @@
       "src/core/client_config/client_config.h", 
       "src/core/client_config/connector.h", 
       "src/core/client_config/initial_connect_string.h", 
+      "src/core/client_config/lb_policies/load_balancer_api.h", 
       "src/core/client_config/lb_policies/pick_first.h", 
       "src/core/client_config/lb_policies/round_robin.h", 
       "src/core/client_config/lb_policy.h", 
@@ -3612,7 +4514,6 @@
       "src/core/iomgr/time_averaged_stats.h", 
       "src/core/iomgr/timer.h", 
       "src/core/iomgr/timer_heap.h", 
-      "src/core/iomgr/timer_internal.h", 
       "src/core/iomgr/udp_server.h", 
       "src/core/iomgr/wakeup_fd_pipe.h", 
       "src/core/iomgr/wakeup_fd_posix.h", 
@@ -3623,6 +4524,7 @@
       "src/core/json/json_common.h", 
       "src/core/json/json_reader.h", 
       "src/core/json/json_writer.h", 
+      "src/core/proto/grpc/lb/v0/load_balancer.pb.h", 
       "src/core/statistics/census_interface.h", 
       "src/core/statistics/census_rpc_stats.h", 
       "src/core/surface/api_trace.h", 
@@ -3661,7 +4563,11 @@
       "src/core/transport/metadata_batch.h", 
       "src/core/transport/static_metadata.h", 
       "src/core/transport/transport.h", 
-      "src/core/transport/transport_impl.h"
+      "src/core/transport/transport_impl.h", 
+      "third_party/nanopb/pb.h", 
+      "third_party/nanopb/pb_common.h", 
+      "third_party/nanopb/pb_decode.h", 
+      "third_party/nanopb/pb_encode.h"
     ], 
     "language": "c", 
     "name": "grpc_unsecure", 
@@ -3678,8 +4584,8 @@
       "src/core/census/grpc_filter.c", 
       "src/core/census/grpc_filter.h", 
       "src/core/census/initialize.c", 
-      "src/core/census/log.c", 
-      "src/core/census/log.h", 
+      "src/core/census/mlog.c", 
+      "src/core/census/mlog.h", 
       "src/core/census/operation.c", 
       "src/core/census/placeholders.c", 
       "src/core/census/rpc_metric_id.h", 
@@ -3710,6 +4616,8 @@
       "src/core/client_config/default_initial_connect_string.c", 
       "src/core/client_config/initial_connect_string.c", 
       "src/core/client_config/initial_connect_string.h", 
+      "src/core/client_config/lb_policies/load_balancer_api.c", 
+      "src/core/client_config/lb_policies/load_balancer_api.h", 
       "src/core/client_config/lb_policies/pick_first.c", 
       "src/core/client_config/lb_policies/pick_first.h", 
       "src/core/client_config/lb_policies/round_robin.c", 
@@ -3738,8 +4646,8 @@
       "src/core/client_config/subchannel_index.h", 
       "src/core/client_config/uri_parser.c", 
       "src/core/client_config/uri_parser.h", 
-      "src/core/compression/algorithm.c", 
       "src/core/compression/algorithm_metadata.h", 
+      "src/core/compression/compression_algorithm.c", 
       "src/core/compression/message_compress.c", 
       "src/core/compression/message_compress.h", 
       "src/core/debug/trace.c", 
@@ -3813,7 +4721,6 @@
       "src/core/iomgr/timer.h", 
       "src/core/iomgr/timer_heap.c", 
       "src/core/iomgr/timer_heap.h", 
-      "src/core/iomgr/timer_internal.h", 
       "src/core/iomgr/udp_server.c", 
       "src/core/iomgr/udp_server.h", 
       "src/core/iomgr/wakeup_fd_eventfd.c", 
@@ -3835,6 +4742,8 @@
       "src/core/json/json_string.c", 
       "src/core/json/json_writer.c", 
       "src/core/json/json_writer.h", 
+      "src/core/proto/grpc/lb/v0/load_balancer.pb.c", 
+      "src/core/proto/grpc/lb/v0/load_balancer.pb.h", 
       "src/core/statistics/census_interface.h", 
       "src/core/statistics/census_rpc_stats.h", 
       "src/core/surface/alarm.c", 
@@ -3924,7 +4833,9 @@
       "src/core/transport/transport.h", 
       "src/core/transport/transport_impl.h", 
       "src/core/transport/transport_op_string.c"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "lib"
   }, 
   {
     "deps": [
@@ -3941,7 +4852,9 @@
       "include/grpc/grpc_zookeeper.h", 
       "src/core/client_config/resolvers/zookeeper_resolver.c", 
       "src/core/client_config/resolvers/zookeeper_resolver.h"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "lib"
   }, 
   {
     "deps": [
@@ -3959,7 +4872,9 @@
     "src": [
       "test/core/util/reconnect_server.c", 
       "test/core/util/reconnect_server.h"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "lib"
   }, 
   {
     "deps": [
@@ -3976,7 +4891,9 @@
     "src": [
       "test/core/util/test_tcp_server.c", 
       "test/core/util/test_tcp_server.h"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "lib"
   }, 
   {
     "deps": [
@@ -4094,7 +5011,6 @@
       "src/cpp/client/secure_credentials.cc", 
       "src/cpp/client/secure_credentials.h", 
       "src/cpp/codegen/grpc_library.cc", 
-      "src/cpp/common/alarm.cc", 
       "src/cpp/common/auth_property_iterator.cc", 
       "src/cpp/common/call.cc", 
       "src/cpp/common/channel_arguments.cc", 
@@ -4105,6 +5021,7 @@
       "src/cpp/common/secure_auth_context.h", 
       "src/cpp/common/secure_channel_arguments.cc", 
       "src/cpp/common/secure_create_auth_context.cc", 
+      "src/cpp/proto/proto_serializer.cc", 
       "src/cpp/proto/proto_utils.cc", 
       "src/cpp/server/async_generic_service.cc", 
       "src/cpp/server/create_default_thread_pool.cc", 
@@ -4123,7 +5040,9 @@
       "src/cpp/util/status.cc", 
       "src/cpp/util/string_ref.cc", 
       "src/cpp/util/time.cc"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "lib"
   }, 
   {
     "deps": [
@@ -4222,7 +5141,9 @@
       "include/grpc/impl/codegen/sync_posix.h", 
       "include/grpc/impl/codegen/sync_win32.h", 
       "include/grpc/impl/codegen/time.h"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "lib"
   }, 
   {
     "deps": [], 
@@ -4234,7 +5155,9 @@
     "src": [
       "test/cpp/util/test_config.cc", 
       "test/cpp/util/test_config.h"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "lib"
   }, 
   {
     "deps": [
@@ -4253,7 +5176,8 @@
       "test/cpp/util/cli_call.h", 
       "test/cpp/util/create_test_channel.h", 
       "test/cpp/util/string_ref_helper.h", 
-      "test/cpp/util/subprocess.h"
+      "test/cpp/util/subprocess.h", 
+      "test/cpp/util/test_credentials_provider.h"
     ], 
     "language": "c++", 
     "name": "grpc++_test_util", 
@@ -4269,8 +5193,12 @@
       "test/cpp/util/string_ref_helper.cc", 
       "test/cpp/util/string_ref_helper.h", 
       "test/cpp/util/subprocess.cc", 
-      "test/cpp/util/subprocess.h"
-    ]
+      "test/cpp/util/subprocess.h", 
+      "test/cpp/util/test_credentials_provider.cc", 
+      "test/cpp/util/test_credentials_provider.h"
+    ], 
+    "third_party": false, 
+    "type": "lib"
   }, 
   {
     "deps": [
@@ -4383,13 +5311,13 @@
       "src/cpp/client/credentials.cc", 
       "src/cpp/client/generic_stub.cc", 
       "src/cpp/client/insecure_credentials.cc", 
-      "src/cpp/common/alarm.cc", 
       "src/cpp/common/call.cc", 
       "src/cpp/common/channel_arguments.cc", 
       "src/cpp/common/completion_queue.cc", 
       "src/cpp/common/create_auth_context.h", 
       "src/cpp/common/insecure_create_auth_context.cc", 
       "src/cpp/common/rpc_method.cc", 
+      "src/cpp/proto/proto_serializer.cc", 
       "src/cpp/proto/proto_utils.cc", 
       "src/cpp/server/async_generic_service.cc", 
       "src/cpp/server/create_default_thread_pool.cc", 
@@ -4406,7 +5334,9 @@
       "src/cpp/util/status.cc", 
       "src/cpp/util/string_ref.cc", 
       "src/cpp/util/time.cc"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "lib"
   }, 
   {
     "deps": [
@@ -4481,7 +5411,9 @@
       "src/compiler/ruby_generator_helpers-inl.h", 
       "src/compiler/ruby_generator_map-inl.h", 
       "src/compiler/ruby_generator_string-inl.h"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "lib"
   }, 
   {
     "deps": [
@@ -4501,7 +5433,9 @@
     "src": [
       "test/cpp/interop/client_helper.cc", 
       "test/cpp/interop/client_helper.h"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "lib"
   }, 
   {
     "deps": [
@@ -4529,7 +5463,9 @@
       "test/cpp/interop/client.cc", 
       "test/cpp/interop/interop_client.cc", 
       "test/cpp/interop/interop_client.h"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "lib"
   }, 
   {
     "deps": [
@@ -4546,7 +5482,9 @@
     "src": [
       "test/cpp/interop/server_helper.cc", 
       "test/cpp/interop/server_helper.h"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "lib"
   }, 
   {
     "deps": [
@@ -4570,8 +5508,10 @@
     "language": "c++", 
     "name": "interop_server_main", 
     "src": [
-      "test/cpp/interop/server.cc"
-    ]
+      "test/cpp/interop/server_main.cc"
+    ], 
+    "third_party": false, 
+    "type": "lib"
   }, 
   {
     "deps": [
@@ -4602,7 +5542,7 @@
       "test/cpp/qps/report.h", 
       "test/cpp/qps/server.h", 
       "test/cpp/qps/stats.h", 
-      "test/cpp/qps/timer.h", 
+      "test/cpp/qps/usage_timer.h", 
       "test/cpp/util/benchmark_config.h"
     ], 
     "language": "c++", 
@@ -4627,11 +5567,13 @@
       "test/cpp/qps/server_async.cc", 
       "test/cpp/qps/server_sync.cc", 
       "test/cpp/qps/stats.h", 
-      "test/cpp/qps/timer.cc", 
-      "test/cpp/qps/timer.h", 
+      "test/cpp/qps/usage_timer.cc", 
+      "test/cpp/qps/usage_timer.h", 
       "test/cpp/util/benchmark_config.cc", 
       "test/cpp/util/benchmark_config.h"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "lib"
   }, 
   {
     "deps": [
@@ -4643,7 +5585,590 @@
     "name": "grpc_csharp_ext", 
     "src": [
       "src/csharp/ext/grpc_csharp_ext.c"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "lib"
+  }, 
+  {
+    "deps": [], 
+    "headers": [
+      "third_party/boringssl/crypto/aes/internal.h", 
+      "third_party/boringssl/crypto/asn1/asn1_locl.h", 
+      "third_party/boringssl/crypto/bio/internal.h", 
+      "third_party/boringssl/crypto/bn/internal.h", 
+      "third_party/boringssl/crypto/bn/rsaz_exp.h", 
+      "third_party/boringssl/crypto/bytestring/internal.h", 
+      "third_party/boringssl/crypto/cipher/internal.h", 
+      "third_party/boringssl/crypto/conf/conf_def.h", 
+      "third_party/boringssl/crypto/conf/internal.h", 
+      "third_party/boringssl/crypto/des/internal.h", 
+      "third_party/boringssl/crypto/dh/internal.h", 
+      "third_party/boringssl/crypto/digest/internal.h", 
+      "third_party/boringssl/crypto/digest/md32_common.h", 
+      "third_party/boringssl/crypto/directory.h", 
+      "third_party/boringssl/crypto/dsa/internal.h", 
+      "third_party/boringssl/crypto/ec/internal.h", 
+      "third_party/boringssl/crypto/ec/p256-x86_64-table.h", 
+      "third_party/boringssl/crypto/evp/internal.h", 
+      "third_party/boringssl/crypto/internal.h", 
+      "third_party/boringssl/crypto/modes/internal.h", 
+      "third_party/boringssl/crypto/obj/obj_dat.h", 
+      "third_party/boringssl/crypto/obj/obj_xref.h", 
+      "third_party/boringssl/crypto/pkcs8/internal.h", 
+      "third_party/boringssl/crypto/rand/internal.h", 
+      "third_party/boringssl/crypto/rsa/internal.h", 
+      "third_party/boringssl/crypto/test/scoped_types.h", 
+      "third_party/boringssl/crypto/test/test_util.h", 
+      "third_party/boringssl/crypto/x509/charmap.h", 
+      "third_party/boringssl/crypto/x509/vpm_int.h", 
+      "third_party/boringssl/crypto/x509v3/ext_dat.h", 
+      "third_party/boringssl/crypto/x509v3/pcy_int.h", 
+      "third_party/boringssl/include/openssl/aead.h", 
+      "third_party/boringssl/include/openssl/aes.h", 
+      "third_party/boringssl/include/openssl/arm_arch.h", 
+      "third_party/boringssl/include/openssl/asn1.h", 
+      "third_party/boringssl/include/openssl/asn1_mac.h", 
+      "third_party/boringssl/include/openssl/asn1t.h", 
+      "third_party/boringssl/include/openssl/base.h", 
+      "third_party/boringssl/include/openssl/base64.h", 
+      "third_party/boringssl/include/openssl/bio.h", 
+      "third_party/boringssl/include/openssl/blowfish.h", 
+      "third_party/boringssl/include/openssl/bn.h", 
+      "third_party/boringssl/include/openssl/buf.h", 
+      "third_party/boringssl/include/openssl/buffer.h", 
+      "third_party/boringssl/include/openssl/bytestring.h", 
+      "third_party/boringssl/include/openssl/cast.h", 
+      "third_party/boringssl/include/openssl/chacha.h", 
+      "third_party/boringssl/include/openssl/cipher.h", 
+      "third_party/boringssl/include/openssl/cmac.h", 
+      "third_party/boringssl/include/openssl/conf.h", 
+      "third_party/boringssl/include/openssl/cpu.h", 
+      "third_party/boringssl/include/openssl/crypto.h", 
+      "third_party/boringssl/include/openssl/curve25519.h", 
+      "third_party/boringssl/include/openssl/des.h", 
+      "third_party/boringssl/include/openssl/dh.h", 
+      "third_party/boringssl/include/openssl/digest.h", 
+      "third_party/boringssl/include/openssl/dsa.h", 
+      "third_party/boringssl/include/openssl/dtls1.h", 
+      "third_party/boringssl/include/openssl/ec.h", 
+      "third_party/boringssl/include/openssl/ec_key.h", 
+      "third_party/boringssl/include/openssl/ecdh.h", 
+      "third_party/boringssl/include/openssl/ecdsa.h", 
+      "third_party/boringssl/include/openssl/engine.h", 
+      "third_party/boringssl/include/openssl/err.h", 
+      "third_party/boringssl/include/openssl/evp.h", 
+      "third_party/boringssl/include/openssl/ex_data.h", 
+      "third_party/boringssl/include/openssl/hkdf.h", 
+      "third_party/boringssl/include/openssl/hmac.h", 
+      "third_party/boringssl/include/openssl/lhash.h", 
+      "third_party/boringssl/include/openssl/lhash_macros.h", 
+      "third_party/boringssl/include/openssl/md4.h", 
+      "third_party/boringssl/include/openssl/md5.h", 
+      "third_party/boringssl/include/openssl/mem.h", 
+      "third_party/boringssl/include/openssl/obj.h", 
+      "third_party/boringssl/include/openssl/obj_mac.h", 
+      "third_party/boringssl/include/openssl/objects.h", 
+      "third_party/boringssl/include/openssl/opensslfeatures.h", 
+      "third_party/boringssl/include/openssl/opensslv.h", 
+      "third_party/boringssl/include/openssl/ossl_typ.h", 
+      "third_party/boringssl/include/openssl/pem.h", 
+      "third_party/boringssl/include/openssl/pkcs12.h", 
+      "third_party/boringssl/include/openssl/pkcs7.h", 
+      "third_party/boringssl/include/openssl/pkcs8.h", 
+      "third_party/boringssl/include/openssl/poly1305.h", 
+      "third_party/boringssl/include/openssl/pqueue.h", 
+      "third_party/boringssl/include/openssl/rand.h", 
+      "third_party/boringssl/include/openssl/rc4.h", 
+      "third_party/boringssl/include/openssl/rsa.h", 
+      "third_party/boringssl/include/openssl/safestack.h", 
+      "third_party/boringssl/include/openssl/sha.h", 
+      "third_party/boringssl/include/openssl/srtp.h", 
+      "third_party/boringssl/include/openssl/ssl.h", 
+      "third_party/boringssl/include/openssl/ssl3.h", 
+      "third_party/boringssl/include/openssl/stack.h", 
+      "third_party/boringssl/include/openssl/stack_macros.h", 
+      "third_party/boringssl/include/openssl/thread.h", 
+      "third_party/boringssl/include/openssl/time_support.h", 
+      "third_party/boringssl/include/openssl/tls1.h", 
+      "third_party/boringssl/include/openssl/type_check.h", 
+      "third_party/boringssl/include/openssl/x509.h", 
+      "third_party/boringssl/include/openssl/x509_vfy.h", 
+      "third_party/boringssl/include/openssl/x509v3.h", 
+      "third_party/boringssl/ssl/internal.h", 
+      "third_party/boringssl/ssl/test/async_bio.h", 
+      "third_party/boringssl/ssl/test/packeted_bio.h", 
+      "third_party/boringssl/ssl/test/scoped_types.h", 
+      "third_party/boringssl/ssl/test/test_config.h"
+    ], 
+    "language": "c", 
+    "name": "boringssl", 
+    "src": [
+      "src/boringssl/err_data.c"
+    ], 
+    "third_party": true, 
+    "type": "lib"
+  }, 
+  {
+    "deps": [], 
+    "headers": [], 
+    "language": "c++", 
+    "name": "boringssl_test_util", 
+    "src": [], 
+    "third_party": true, 
+    "type": "lib"
+  }, 
+  {
+    "deps": [
+      "boringssl", 
+      "boringssl_test_util"
+    ], 
+    "headers": [], 
+    "language": "c++", 
+    "name": "boringssl_aes_test_lib", 
+    "src": [], 
+    "third_party": true, 
+    "type": "lib"
+  }, 
+  {
+    "deps": [
+      "boringssl", 
+      "boringssl_test_util"
+    ], 
+    "headers": [], 
+    "language": "c++", 
+    "name": "boringssl_base64_test_lib", 
+    "src": [], 
+    "third_party": true, 
+    "type": "lib"
+  }, 
+  {
+    "deps": [
+      "boringssl", 
+      "boringssl_test_util"
+    ], 
+    "headers": [], 
+    "language": "c++", 
+    "name": "boringssl_bio_test_lib", 
+    "src": [], 
+    "third_party": true, 
+    "type": "lib"
+  }, 
+  {
+    "deps": [
+      "boringssl", 
+      "boringssl_test_util"
+    ], 
+    "headers": [], 
+    "language": "c++", 
+    "name": "boringssl_bn_test_lib", 
+    "src": [], 
+    "third_party": true, 
+    "type": "lib"
+  }, 
+  {
+    "deps": [
+      "boringssl", 
+      "boringssl_test_util"
+    ], 
+    "headers": [], 
+    "language": "c++", 
+    "name": "boringssl_bytestring_test_lib", 
+    "src": [], 
+    "third_party": true, 
+    "type": "lib"
+  }, 
+  {
+    "deps": [
+      "boringssl", 
+      "boringssl_test_util"
+    ], 
+    "headers": [], 
+    "language": "c++", 
+    "name": "boringssl_aead_test_lib", 
+    "src": [], 
+    "third_party": true, 
+    "type": "lib"
+  }, 
+  {
+    "deps": [
+      "boringssl", 
+      "boringssl_test_util"
+    ], 
+    "headers": [], 
+    "language": "c++", 
+    "name": "boringssl_cipher_test_lib", 
+    "src": [], 
+    "third_party": true, 
+    "type": "lib"
+  }, 
+  {
+    "deps": [
+      "boringssl", 
+      "boringssl_test_util"
+    ], 
+    "headers": [], 
+    "language": "c++", 
+    "name": "boringssl_cmac_test_lib", 
+    "src": [], 
+    "third_party": true, 
+    "type": "lib"
+  }, 
+  {
+    "deps": [
+      "boringssl", 
+      "boringssl_test_util"
+    ], 
+    "headers": [], 
+    "language": "c", 
+    "name": "boringssl_constant_time_test_lib", 
+    "src": [], 
+    "third_party": true, 
+    "type": "lib"
+  }, 
+  {
+    "deps": [
+      "boringssl", 
+      "boringssl_test_util"
+    ], 
+    "headers": [], 
+    "language": "c++", 
+    "name": "boringssl_ed25519_test_lib", 
+    "src": [], 
+    "third_party": true, 
+    "type": "lib"
+  }, 
+  {
+    "deps": [
+      "boringssl", 
+      "boringssl_test_util"
+    ], 
+    "headers": [], 
+    "language": "c++", 
+    "name": "boringssl_x25519_test_lib", 
+    "src": [], 
+    "third_party": true, 
+    "type": "lib"
+  }, 
+  {
+    "deps": [
+      "boringssl", 
+      "boringssl_test_util"
+    ], 
+    "headers": [], 
+    "language": "c++", 
+    "name": "boringssl_dh_test_lib", 
+    "src": [], 
+    "third_party": true, 
+    "type": "lib"
+  }, 
+  {
+    "deps": [
+      "boringssl", 
+      "boringssl_test_util"
+    ], 
+    "headers": [], 
+    "language": "c++", 
+    "name": "boringssl_digest_test_lib", 
+    "src": [], 
+    "third_party": true, 
+    "type": "lib"
+  }, 
+  {
+    "deps": [
+      "boringssl", 
+      "boringssl_test_util"
+    ], 
+    "headers": [], 
+    "language": "c", 
+    "name": "boringssl_dsa_test_lib", 
+    "src": [], 
+    "third_party": true, 
+    "type": "lib"
+  }, 
+  {
+    "deps": [
+      "boringssl", 
+      "boringssl_test_util"
+    ], 
+    "headers": [], 
+    "language": "c++", 
+    "name": "boringssl_ec_test_lib", 
+    "src": [], 
+    "third_party": true, 
+    "type": "lib"
+  }, 
+  {
+    "deps": [
+      "boringssl", 
+      "boringssl_test_util"
+    ], 
+    "headers": [], 
+    "language": "c", 
+    "name": "boringssl_example_mul_lib", 
+    "src": [], 
+    "third_party": true, 
+    "type": "lib"
+  }, 
+  {
+    "deps": [
+      "boringssl", 
+      "boringssl_test_util"
+    ], 
+    "headers": [], 
+    "language": "c++", 
+    "name": "boringssl_ecdsa_test_lib", 
+    "src": [], 
+    "third_party": true, 
+    "type": "lib"
+  }, 
+  {
+    "deps": [
+      "boringssl", 
+      "boringssl_test_util"
+    ], 
+    "headers": [], 
+    "language": "c++", 
+    "name": "boringssl_err_test_lib", 
+    "src": [], 
+    "third_party": true, 
+    "type": "lib"
+  }, 
+  {
+    "deps": [
+      "boringssl", 
+      "boringssl_test_util"
+    ], 
+    "headers": [], 
+    "language": "c++", 
+    "name": "boringssl_evp_extra_test_lib", 
+    "src": [], 
+    "third_party": true, 
+    "type": "lib"
+  }, 
+  {
+    "deps": [
+      "boringssl", 
+      "boringssl_test_util"
+    ], 
+    "headers": [], 
+    "language": "c++", 
+    "name": "boringssl_evp_test_lib", 
+    "src": [], 
+    "third_party": true, 
+    "type": "lib"
+  }, 
+  {
+    "deps": [
+      "boringssl", 
+      "boringssl_test_util"
+    ], 
+    "headers": [], 
+    "language": "c++", 
+    "name": "boringssl_pbkdf_test_lib", 
+    "src": [], 
+    "third_party": true, 
+    "type": "lib"
+  }, 
+  {
+    "deps": [
+      "boringssl", 
+      "boringssl_test_util"
+    ], 
+    "headers": [], 
+    "language": "c", 
+    "name": "boringssl_hkdf_test_lib", 
+    "src": [], 
+    "third_party": true, 
+    "type": "lib"
+  }, 
+  {
+    "deps": [
+      "boringssl", 
+      "boringssl_test_util"
+    ], 
+    "headers": [], 
+    "language": "c++", 
+    "name": "boringssl_hmac_test_lib", 
+    "src": [], 
+    "third_party": true, 
+    "type": "lib"
+  }, 
+  {
+    "deps": [
+      "boringssl", 
+      "boringssl_test_util"
+    ], 
+    "headers": [], 
+    "language": "c", 
+    "name": "boringssl_lhash_test_lib", 
+    "src": [], 
+    "third_party": true, 
+    "type": "lib"
+  }, 
+  {
+    "deps": [
+      "boringssl", 
+      "boringssl_test_util"
+    ], 
+    "headers": [], 
+    "language": "c", 
+    "name": "boringssl_gcm_test_lib", 
+    "src": [], 
+    "third_party": true, 
+    "type": "lib"
+  }, 
+  {
+    "deps": [
+      "boringssl", 
+      "boringssl_test_util"
+    ], 
+    "headers": [], 
+    "language": "c++", 
+    "name": "boringssl_pkcs12_test_lib", 
+    "src": [], 
+    "third_party": true, 
+    "type": "lib"
+  }, 
+  {
+    "deps": [
+      "boringssl", 
+      "boringssl_test_util"
+    ], 
+    "headers": [], 
+    "language": "c++", 
+    "name": "boringssl_pkcs8_test_lib", 
+    "src": [], 
+    "third_party": true, 
+    "type": "lib"
+  }, 
+  {
+    "deps": [
+      "boringssl", 
+      "boringssl_test_util"
+    ], 
+    "headers": [], 
+    "language": "c++", 
+    "name": "boringssl_poly1305_test_lib", 
+    "src": [], 
+    "third_party": true, 
+    "type": "lib"
+  }, 
+  {
+    "deps": [
+      "boringssl", 
+      "boringssl_test_util"
+    ], 
+    "headers": [], 
+    "language": "c", 
+    "name": "boringssl_refcount_test_lib", 
+    "src": [], 
+    "third_party": true, 
+    "type": "lib"
+  }, 
+  {
+    "deps": [
+      "boringssl", 
+      "boringssl_test_util"
+    ], 
+    "headers": [], 
+    "language": "c++", 
+    "name": "boringssl_rsa_test_lib", 
+    "src": [], 
+    "third_party": true, 
+    "type": "lib"
+  }, 
+  {
+    "deps": [
+      "boringssl", 
+      "boringssl_test_util"
+    ], 
+    "headers": [], 
+    "language": "c", 
+    "name": "boringssl_thread_test_lib", 
+    "src": [], 
+    "third_party": true, 
+    "type": "lib"
+  }, 
+  {
+    "deps": [
+      "boringssl", 
+      "boringssl_test_util"
+    ], 
+    "headers": [], 
+    "language": "c", 
+    "name": "boringssl_pkcs7_test_lib", 
+    "src": [], 
+    "third_party": true, 
+    "type": "lib"
+  }, 
+  {
+    "deps": [
+      "boringssl", 
+      "boringssl_test_util"
+    ], 
+    "headers": [], 
+    "language": "c", 
+    "name": "boringssl_tab_test_lib", 
+    "src": [], 
+    "third_party": true, 
+    "type": "lib"
+  }, 
+  {
+    "deps": [
+      "boringssl", 
+      "boringssl_test_util"
+    ], 
+    "headers": [], 
+    "language": "c", 
+    "name": "boringssl_v3name_test_lib", 
+    "src": [], 
+    "third_party": true, 
+    "type": "lib"
+  }, 
+  {
+    "deps": [
+      "boringssl", 
+      "boringssl_test_util"
+    ], 
+    "headers": [], 
+    "language": "c", 
+    "name": "boringssl_pqueue_test_lib", 
+    "src": [], 
+    "third_party": true, 
+    "type": "lib"
+  }, 
+  {
+    "deps": [
+      "boringssl", 
+      "boringssl_test_util"
+    ], 
+    "headers": [], 
+    "language": "c++", 
+    "name": "boringssl_ssl_test_lib", 
+    "src": [], 
+    "third_party": true, 
+    "type": "lib"
+  }, 
+  {
+    "deps": [], 
+    "headers": [
+      "third_party/zlib/crc32.h", 
+      "third_party/zlib/deflate.h", 
+      "third_party/zlib/gzguts.h", 
+      "third_party/zlib/inffast.h", 
+      "third_party/zlib/inffixed.h", 
+      "third_party/zlib/inflate.h", 
+      "third_party/zlib/inftrees.h", 
+      "third_party/zlib/trees.h", 
+      "third_party/zlib/zconf.h", 
+      "third_party/zlib/zlib.h", 
+      "third_party/zlib/zutil.h"
+    ], 
+    "language": "c", 
+    "name": "z", 
+    "src": [], 
+    "third_party": true, 
+    "type": "lib"
   }, 
   {
     "deps": [
@@ -4660,7 +6185,9 @@
     "src": [
       "test/core/bad_client/bad_client.c", 
       "test/core/bad_client/bad_client.h"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "lib"
   }, 
   {
     "deps": [
@@ -4670,14 +6197,16 @@
       "grpc_test_util"
     ], 
     "headers": [
-      "test/core/bad_ssl/server.h"
+      "test/core/bad_ssl/server_common.h"
     ], 
     "language": "c", 
     "name": "bad_ssl_test_server", 
     "src": [
-      "test/core/bad_ssl/server.c", 
-      "test/core/bad_ssl/server.h"
-    ]
+      "test/core/bad_ssl/server_common.c", 
+      "test/core/bad_ssl/server_common.h"
+    ], 
+    "third_party": false, 
+    "type": "lib"
   }, 
   {
     "deps": [
@@ -4706,9 +6235,8 @@
       "test/core/end2end/tests/cancel_in_a_vacuum.c", 
       "test/core/end2end/tests/cancel_test_helpers.h", 
       "test/core/end2end/tests/cancel_with_status.c", 
-      "test/core/end2end/tests/channel_connectivity.c", 
-      "test/core/end2end/tests/channel_ping.c", 
       "test/core/end2end/tests/compressed_payload.c", 
+      "test/core/end2end/tests/connectivity.c", 
       "test/core/end2end/tests/default_host.c", 
       "test/core/end2end/tests/disappearing_server.c", 
       "test/core/end2end/tests/empty_batch.c", 
@@ -4719,10 +6247,10 @@
       "test/core/end2end/tests/large_metadata.c", 
       "test/core/end2end/tests/max_concurrent_streams.c", 
       "test/core/end2end/tests/max_message_length.c", 
-      "test/core/end2end/tests/metadata.c", 
       "test/core/end2end/tests/negative_deadline.c", 
       "test/core/end2end/tests/no_op.c", 
       "test/core/end2end/tests/payload.c", 
+      "test/core/end2end/tests/ping.c", 
       "test/core/end2end/tests/ping_pong_streaming.c", 
       "test/core/end2end/tests/registered_call.c", 
       "test/core/end2end/tests/request_with_flags.c", 
@@ -4731,9 +6259,12 @@
       "test/core/end2end/tests/shutdown_finishes_calls.c", 
       "test/core/end2end/tests/shutdown_finishes_tags.c", 
       "test/core/end2end/tests/simple_delayed_request.c", 
+      "test/core/end2end/tests/simple_metadata.c", 
       "test/core/end2end/tests/simple_request.c", 
       "test/core/end2end/tests/trailing_metadata.c"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "lib"
   }, 
   {
     "deps": [
@@ -4760,9 +6291,8 @@
       "test/core/end2end/tests/cancel_in_a_vacuum.c", 
       "test/core/end2end/tests/cancel_test_helpers.h", 
       "test/core/end2end/tests/cancel_with_status.c", 
-      "test/core/end2end/tests/channel_connectivity.c", 
-      "test/core/end2end/tests/channel_ping.c", 
       "test/core/end2end/tests/compressed_payload.c", 
+      "test/core/end2end/tests/connectivity.c", 
       "test/core/end2end/tests/default_host.c", 
       "test/core/end2end/tests/disappearing_server.c", 
       "test/core/end2end/tests/empty_batch.c", 
@@ -4773,10 +6303,10 @@
       "test/core/end2end/tests/large_metadata.c", 
       "test/core/end2end/tests/max_concurrent_streams.c", 
       "test/core/end2end/tests/max_message_length.c", 
-      "test/core/end2end/tests/metadata.c", 
       "test/core/end2end/tests/negative_deadline.c", 
       "test/core/end2end/tests/no_op.c", 
       "test/core/end2end/tests/payload.c", 
+      "test/core/end2end/tests/ping.c", 
       "test/core/end2end/tests/ping_pong_streaming.c", 
       "test/core/end2end/tests/registered_call.c", 
       "test/core/end2end/tests/request_with_flags.c", 
@@ -4785,9 +6315,12 @@
       "test/core/end2end/tests/shutdown_finishes_calls.c", 
       "test/core/end2end/tests/shutdown_finishes_tags.c", 
       "test/core/end2end/tests/simple_delayed_request.c", 
+      "test/core/end2end/tests/simple_metadata.c", 
       "test/core/end2end/tests/simple_request.c", 
       "test/core/end2end/tests/trailing_metadata.c"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "lib"
   }, 
   {
     "deps": [], 
@@ -4798,6 +6331,8 @@
       "test/core/end2end/data/server1_cert.c", 
       "test/core/end2end/data/server1_key.c", 
       "test/core/end2end/data/test_root_cert.c"
-    ]
+    ], 
+    "third_party": false, 
+    "type": "lib"
   }
 ]
diff --git a/tools/run_tests/stress_test/run_stress_tests_on_gke.py b/tools/run_tests/stress_test/run_stress_tests_on_gke.py
new file mode 100755
index 0000000..634eb1a
--- /dev/null
+++ b/tools/run_tests/stress_test/run_stress_tests_on_gke.py
@@ -0,0 +1,556 @@
+#!/usr/bin/env python2.7
+# Copyright 2015-2016, Google Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#     * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+#     * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+import argparse
+import datetime
+import os
+import subprocess
+import sys
+import time
+
+stress_test_utils_dir = os.path.abspath(os.path.join(
+    os.path.dirname(__file__), '../../gcp/stress_test'))
+sys.path.append(stress_test_utils_dir)
+from stress_test_utils import BigQueryHelper
+
+kubernetes_api_dir = os.path.abspath(os.path.join(
+    os.path.dirname(__file__), '../../gcp/utils'))
+sys.path.append(kubernetes_api_dir)
+
+import kubernetes_api
+
+_GRPC_ROOT = os.path.abspath(os.path.join(
+    os.path.dirname(sys.argv[0]), '../../..'))
+os.chdir(_GRPC_ROOT)
+
+# num of seconds to wait for the GKE image to start and warmup
+_GKE_IMAGE_WARMUP_WAIT_SECS = 60
+
+_SERVER_POD_NAME = 'stress-server'
+_CLIENT_POD_NAME_PREFIX = 'stress-client'
+_DATASET_ID_PREFIX = 'stress_test'
+_SUMMARY_TABLE_ID = 'summary'
+_QPS_TABLE_ID = 'qps'
+
+_DEFAULT_DOCKER_IMAGE_NAME = 'grpc_stress_test'
+
+# The default port on which the kubernetes proxy server is started on localhost
+# (i.e kubectl proxy --port=<port>)
+_DEFAULT_KUBERNETES_PROXY_PORT = 8001
+
+# How frequently should the stress client wrapper script (running inside a GKE
+# container) poll the health of the stress client (also running inside the GKE
+# container) and upload metrics to BigQuery
+_DEFAULT_STRESS_CLIENT_POLL_INTERVAL_SECS = 60
+
+# The default setting for stress test server and client
+_DEFAULT_STRESS_SERVER_PORT = 8080
+_DEFAULT_METRICS_PORT = 8081
+_DEFAULT_TEST_CASES_STR = 'empty_unary:1,large_unary:1,client_streaming:1,server_streaming:1,empty_stream:1'
+_DEFAULT_NUM_CHANNELS_PER_SERVER = 5
+_DEFAULT_NUM_STUBS_PER_CHANNEL = 10
+_DEFAULT_METRICS_COLLECTION_INTERVAL_SECS = 30
+
+# Number of stress client instances to launch
+_DEFAULT_NUM_CLIENTS = 3
+
+# How frequently should this test monitor the health of Stress clients and
+# Servers running in GKE
+_DEFAULT_TEST_POLL_INTERVAL_SECS = 60
+
+# Default run time for this test (2 hour)
+_DEFAULT_TEST_DURATION_SECS = 7200
+
+# The number of seconds it would take a GKE pod to warm up (i.e get to 'Running'
+# state from the time of creation). Ideally this is something the test should
+# automatically determine by using Kubernetes API to poll the pods status.
+_DEFAULT_GKE_WARMUP_SECS = 60
+
+
+class KubernetesProxy:
+  """ Class to start a proxy on localhost to the Kubernetes API server """
+
+  def __init__(self, api_port):
+    self.port = api_port
+    self.p = None
+    self.started = False
+
+  def start(self):
+    cmd = ['kubectl', 'proxy', '--port=%d' % self.port]
+    self.p = subprocess.Popen(args=cmd)
+    self.started = True
+    time.sleep(2)
+    print '..Started'
+
+  def get_port(self):
+    return self.port
+
+  def is_started(self):
+    return self.started
+
+  def __del__(self):
+    if self.p is not None:
+      print 'Shutting down Kubernetes proxy..'
+      self.p.kill()
+
+
+class TestSettings:
+
+  def __init__(self, build_docker_image, test_poll_interval_secs,
+               test_duration_secs, kubernetes_proxy_port):
+    self.build_docker_image = build_docker_image
+    self.test_poll_interval_secs = test_poll_interval_secs
+    self.test_duration_secs = test_duration_secs
+    self.kubernetes_proxy_port = kubernetes_proxy_port
+
+
+class GkeSettings:
+
+  def __init__(self, project_id, docker_image_name):
+    self.project_id = project_id
+    self.docker_image_name = docker_image_name
+    self.tag_name = 'gcr.io/%s/%s' % (project_id, docker_image_name)
+
+
+class BigQuerySettings:
+
+  def __init__(self, run_id, dataset_id, summary_table_id, qps_table_id):
+    self.run_id = run_id
+    self.dataset_id = dataset_id
+    self.summary_table_id = summary_table_id
+    self.qps_table_id = qps_table_id
+
+
+class StressServerSettings:
+
+  def __init__(self, server_pod_name, server_port):
+    self.server_pod_name = server_pod_name
+    self.server_port = server_port
+
+
+class StressClientSettings:
+
+  def __init__(self, num_clients, client_pod_name_prefix, server_pod_name,
+               server_port, metrics_port, metrics_collection_interval_secs,
+               stress_client_poll_interval_secs, num_channels_per_server,
+               num_stubs_per_channel, test_cases_str):
+    self.num_clients = num_clients
+    self.client_pod_name_prefix = client_pod_name_prefix
+    self.server_pod_name = server_pod_name
+    self.server_port = server_port
+    self.metrics_port = metrics_port
+    self.metrics_collection_interval_secs = metrics_collection_interval_secs
+    self.stress_client_poll_interval_secs = stress_client_poll_interval_secs
+    self.num_channels_per_server = num_channels_per_server
+    self.num_stubs_per_channel = num_stubs_per_channel
+    self.test_cases_str = test_cases_str
+
+    # == Derived properties ==
+    # Note: Client can accept a list of server addresses (a comma separated list
+    # of 'server_name:server_port'). In this case, we only have one server
+    # address to pass
+    self.server_addresses = '%s.default.svc.cluster.local:%d' % (
+        server_pod_name, server_port)
+    self.client_pod_names_list = ['%s-%d' % (client_pod_name_prefix, i)
+                                  for i in range(1, num_clients + 1)]
+
+
+def _build_docker_image(image_name, tag_name):
+  """ Build the docker image and add tag it to the GKE repository """
+  print 'Building docker image: %s' % image_name
+  os.environ['INTEROP_IMAGE'] = image_name
+  os.environ['INTEROP_IMAGE_REPOSITORY_TAG'] = tag_name
+  # Note that 'BASE_NAME' HAS to be 'grpc_interop_stress_cxx' since the script
+  # build_interop_stress_image.sh invokes the following script:
+  #   tools/dockerfile/$BASE_NAME/build_interop_stress.sh
+  os.environ['BASE_NAME'] = 'grpc_interop_stress_cxx'
+  cmd = ['tools/jenkins/build_interop_stress_image.sh']
+  retcode = subprocess.call(args=cmd)
+  if retcode != 0:
+    print 'Error in building docker image'
+    return False
+  return True
+
+
+def _push_docker_image_to_gke_registry(docker_tag_name):
+  """Executes 'gcloud docker push <docker_tag_name>' to push the image to GKE registry"""
+  cmd = ['gcloud', 'docker', 'push', docker_tag_name]
+  print 'Pushing %s to GKE registry..' % docker_tag_name
+  retcode = subprocess.call(args=cmd)
+  if retcode != 0:
+    print 'Error in pushing docker image %s to the GKE registry' % docker_tag_name
+    return False
+  return True
+
+
+def _launch_server(gke_settings, stress_server_settings, bq_settings,
+                   kubernetes_proxy):
+  """ Launches a stress test server instance in GKE cluster """
+  if not kubernetes_proxy.is_started:
+    print 'Kubernetes proxy must be started before calling this function'
+    return False
+
+  # This is the wrapper script that is run in the container. This script runs
+  # the actual stress test server
+  server_cmd_list = ['/var/local/git/grpc/tools/gcp/stress_test/run_server.py']
+
+  # run_server.py does not take any args from the command line. The args are
+  # instead passed via environment variables (see server_env below)
+  server_arg_list = []
+
+  # The parameters to the script run_server.py are injected into the container
+  # via environment variables
+  server_env = {
+      'STRESS_TEST_IMAGE_TYPE': 'SERVER',
+      'STRESS_TEST_IMAGE': '/var/local/git/grpc/bins/opt/interop_server',
+      'STRESS_TEST_ARGS_STR': '--port=%s' % stress_server_settings.server_port,
+      'RUN_ID': bq_settings.run_id,
+      'POD_NAME': stress_server_settings.server_pod_name,
+      'GCP_PROJECT_ID': gke_settings.project_id,
+      'DATASET_ID': bq_settings.dataset_id,
+      'SUMMARY_TABLE_ID': bq_settings.summary_table_id,
+      'QPS_TABLE_ID': bq_settings.qps_table_id
+  }
+
+  # Launch Server
+  is_success = kubernetes_api.create_pod_and_service(
+      'localhost',
+      kubernetes_proxy.get_port(),
+      'default',  # Use 'default' namespace
+      stress_server_settings.server_pod_name,
+      gke_settings.tag_name,
+      [stress_server_settings.server_port],  # Port that should be exposed
+      server_cmd_list,
+      server_arg_list,
+      server_env,
+      True  # Headless = True for server. Since we want DNS records to be created by GKE
+  )
+
+  return is_success
+
+
+def _launch_client(gke_settings, stress_server_settings, stress_client_settings,
+                   bq_settings, kubernetes_proxy):
+  """ Launches a configurable number of stress test clients on GKE cluster """
+  if not kubernetes_proxy.is_started:
+    print 'Kubernetes proxy must be started before calling this function'
+    return False
+
+  stress_client_arg_list = [
+      '--server_addresses=%s' % stress_client_settings.server_addresses,
+      '--test_cases=%s' % stress_client_settings.test_cases_str,
+      '--num_stubs_per_channel=%d' %
+      stress_client_settings.num_stubs_per_channel
+  ]
+
+  # This is the wrapper script that is run in the container. This script runs
+  # the actual stress client
+  client_cmd_list = ['/var/local/git/grpc/tools/gcp/stress_test/run_client.py']
+
+  # run_client.py takes no args. All args are passed as env variables (see
+  # client_env)
+  client_arg_list = []
+
+  metrics_server_address = 'localhost:%d' % stress_client_settings.metrics_port
+  metrics_client_arg_list = [
+      '--metrics_server_address=%s' % metrics_server_address,
+      '--total_only=true'
+  ]
+
+  # The parameters to the script run_client.py are injected into the container
+  # via environment variables
+  client_env = {
+      'STRESS_TEST_IMAGE_TYPE': 'CLIENT',
+      'STRESS_TEST_IMAGE': '/var/local/git/grpc/bins/opt/stress_test',
+      'STRESS_TEST_ARGS_STR': ' '.join(stress_client_arg_list),
+      'METRICS_CLIENT_IMAGE': '/var/local/git/grpc/bins/opt/metrics_client',
+      'METRICS_CLIENT_ARGS_STR': ' '.join(metrics_client_arg_list),
+      'RUN_ID': bq_settings.run_id,
+      'POLL_INTERVAL_SECS':
+          str(stress_client_settings.stress_client_poll_interval_secs),
+      'GCP_PROJECT_ID': gke_settings.project_id,
+      'DATASET_ID': bq_settings.dataset_id,
+      'SUMMARY_TABLE_ID': bq_settings.summary_table_id,
+      'QPS_TABLE_ID': bq_settings.qps_table_id
+  }
+
+  for pod_name in stress_client_settings.client_pod_names_list:
+    client_env['POD_NAME'] = pod_name
+    is_success = kubernetes_api.create_pod_and_service(
+        'localhost',  # Since proxy is running on localhost
+        kubernetes_proxy.get_port(),
+        'default',  # default namespace
+        pod_name,
+        gke_settings.tag_name,
+        [stress_client_settings.metrics_port
+        ],  # Client pods expose metrics port
+        client_cmd_list,
+        client_arg_list,
+        client_env,
+        False  # Client is not a headless service
+    )
+    if not is_success:
+      print 'Error in launching client %s' % pod_name
+      return False
+
+  return True
+
+
+def _launch_server_and_client(gke_settings, stress_server_settings,
+                              stress_client_settings, bq_settings,
+                              kubernetes_proxy_port):
+  # Start kubernetes proxy
+  print 'Kubernetes proxy'
+  kubernetes_proxy = KubernetesProxy(kubernetes_proxy_port)
+  kubernetes_proxy.start()
+
+  print 'Launching server..'
+  is_success = _launch_server(gke_settings, stress_server_settings, bq_settings,
+                              kubernetes_proxy)
+  if not is_success:
+    print 'Error in launching server'
+    return False
+
+  # Server takes a while to start.
+  # TODO(sree) Use Kubernetes API to query the status of the server instead of
+  # sleeping
+  print 'Waiting for %s seconds for the server to start...' % _GKE_IMAGE_WARMUP_WAIT_SECS
+  time.sleep(_GKE_IMAGE_WARMUP_WAIT_SECS)
+
+  # Launch client
+  client_pod_name_prefix = 'stress-client'
+  is_success = _launch_client(gke_settings, stress_server_settings,
+                              stress_client_settings, bq_settings,
+                              kubernetes_proxy)
+
+  if not is_success:
+    print 'Error in launching client(s)'
+    return False
+
+  print 'Waiting for %s seconds for the client images to start...' % _GKE_IMAGE_WARMUP_WAIT_SECS
+  time.sleep(_GKE_IMAGE_WARMUP_WAIT_SECS)
+  return True
+
+
+def _delete_server_and_client(stress_server_settings, stress_client_settings,
+                              kubernetes_proxy_port):
+  kubernetes_proxy = KubernetesProxy(kubernetes_proxy_port)
+  kubernetes_proxy.start()
+
+  # Delete clients first
+  is_success = True
+  for pod_name in stress_client_settings.client_pod_names_list:
+    is_success = kubernetes_api.delete_pod_and_service(
+        'localhost', kubernetes_proxy_port, 'default', pod_name)
+    if not is_success:
+      return False
+
+  # Delete server
+  is_success = kubernetes_api.delete_pod_and_service(
+      'localhost', kubernetes_proxy_port, 'default',
+      stress_server_settings.server_pod_name)
+  return is_success
+
+
+def run_test_main(test_settings, gke_settings, stress_server_settings,
+                  stress_client_clients):
+  is_success = True
+
+  if test_settings.build_docker_image:
+    is_success = _build_docker_image(gke_settings.docker_image_name,
+                                     gke_settings.tag_name)
+    if not is_success:
+      return False
+
+    is_success = _push_docker_image_to_gke_registry(gke_settings.tag_name)
+    if not is_success:
+      return False
+
+  # Create a unique id for this run (Note: Using timestamp instead of UUID to
+  # make it easier to deduce the date/time of the run just by looking at the run
+  # run id. This is useful in debugging when looking at records in Biq query)
+  run_id = datetime.datetime.now().strftime('%Y_%m_%d_%H_%M_%S')
+  dataset_id = '%s_%s' % (_DATASET_ID_PREFIX, run_id)
+
+  # Big Query settings (common for both Stress Server and Client)
+  bq_settings = BigQuerySettings(run_id, dataset_id, _SUMMARY_TABLE_ID,
+                                 _QPS_TABLE_ID)
+
+  bq_helper = BigQueryHelper(run_id, '', '', args.project_id, dataset_id,
+                             _SUMMARY_TABLE_ID, _QPS_TABLE_ID)
+  bq_helper.initialize()
+
+  try:
+    is_success = _launch_server_and_client(gke_settings, stress_server_settings,
+                                           stress_client_settings, bq_settings,
+                                           test_settings.kubernetes_proxy_port)
+    if not is_success:
+      return False
+
+    start_time = datetime.datetime.now()
+    end_time = start_time + datetime.timedelta(
+        seconds=test_settings.test_duration_secs)
+    print 'Running the test until %s' % end_time.isoformat()
+
+    while True:
+      if datetime.datetime.now() > end_time:
+        print 'Test was run for %d seconds' % test_settings.test_duration_secs
+        break
+
+      # Check if either stress server or clients have failed
+      if bq_helper.check_if_any_tests_failed():
+        is_success = False
+        print 'Some tests failed.'
+        break
+
+      # Things seem to be running fine. Wait until next poll time to check the
+      # status
+      print 'Sleeping for %d seconds..' % test_settings.test_poll_interval_secs
+      time.sleep(test_settings.test_poll_interval_secs)
+
+    # Print BiqQuery tables
+    bq_helper.print_summary_records()
+    bq_helper.print_qps_records()
+
+  finally:
+    # If is_success is False at this point, it means that the stress tests were
+    # started successfully but failed while running the tests. In this case we
+    # do should not delete the pods (since they contain all the failure
+    # information)
+    if is_success:
+      _delete_server_and_client(stress_server_settings, stress_client_settings,
+                                test_settings.kubernetes_proxy_port)
+
+  return is_success
+
+
+argp = argparse.ArgumentParser(
+    description='Launch stress tests in GKE',
+    formatter_class=argparse.ArgumentDefaultsHelpFormatter)
+argp.add_argument('--project_id',
+                  required=True,
+                  help='The Google Cloud Platform Project Id')
+argp.add_argument('--num_clients',
+                  default=1,
+                  type=int,
+                  help='Number of client instances to start')
+argp.add_argument('--docker_image_name',
+                  default=_DEFAULT_DOCKER_IMAGE_NAME,
+                  help='The name of the docker image containing stress client '
+                  'and stress servers')
+argp.add_argument('--build_docker_image',
+                  dest='build_docker_image',
+                  action='store_true',
+                  help='Build a docker image and push to Google Container '
+                  'Registry')
+argp.add_argument('--do_not_build_docker_image',
+                  dest='build_docker_image',
+                  action='store_false',
+                  help='Do not build and push docker image to Google Container '
+                  'Registry')
+argp.set_defaults(build_docker_image=True)
+
+argp.add_argument('--test_poll_interval_secs',
+                  default=_DEFAULT_TEST_POLL_INTERVAL_SECS,
+                  type=int,
+                  help='How frequently should this script should monitor the '
+                  'health of stress clients and servers running in the GKE '
+                  'cluster')
+argp.add_argument('--test_duration_secs',
+                  default=_DEFAULT_TEST_DURATION_SECS,
+                  type=int,
+                  help='How long should this test be run')
+argp.add_argument('--kubernetes_proxy_port',
+                  default=_DEFAULT_KUBERNETES_PROXY_PORT,
+                  type=int,
+                  help='The port on which the kubernetes proxy (on localhost)'
+                  ' is started')
+argp.add_argument('--stress_server_port',
+                  default=_DEFAULT_STRESS_SERVER_PORT,
+                  type=int,
+                  help='The port on which the stress server (in GKE '
+                  'containers) listens')
+argp.add_argument('--stress_client_metrics_port',
+                  default=_DEFAULT_METRICS_PORT,
+                  type=int,
+                  help='The port on which the stress clients (in GKE '
+                  'containers) expose metrics')
+argp.add_argument('--stress_client_poll_interval_secs',
+                  default=_DEFAULT_STRESS_CLIENT_POLL_INTERVAL_SECS,
+                  type=int,
+                  help='How frequently should the stress client wrapper script'
+                  ' running inside GKE should monitor health of the actual '
+                  ' stress client process and upload the metrics to BigQuery')
+argp.add_argument('--stress_client_metrics_collection_interval_secs',
+                  default=_DEFAULT_METRICS_COLLECTION_INTERVAL_SECS,
+                  type=int,
+                  help='How frequently should metrics be collected in-memory on'
+                  ' the stress clients (running inside GKE containers). Note '
+                  'that this is NOT the same as the upload-to-BigQuery '
+                  'frequency. The metrics upload frequency is controlled by the'
+                  ' --stress_client_poll_interval_secs flag')
+argp.add_argument('--stress_client_num_channels_per_server',
+                  default=_DEFAULT_NUM_CHANNELS_PER_SERVER,
+                  type=int,
+                  help='The number of channels created to each server from a '
+                  'stress client')
+argp.add_argument('--stress_client_num_stubs_per_channel',
+                  default=_DEFAULT_NUM_STUBS_PER_CHANNEL,
+                  type=int,
+                  help='The number of stubs created per channel. This number '
+                  'indicates the max number of RPCs that can be made in '
+                  'parallel on each channel at any given time')
+argp.add_argument('--stress_client_test_cases',
+                  default=_DEFAULT_TEST_CASES_STR,
+                  help='List of test cases (with weights) to be executed by the'
+                  ' stress test client. The list is in the following format:\n'
+                  '  <testcase_1:w_1,<test_case2:w_2>..<testcase_n:w_n>\n'
+                  ' (Note: The weights do not have to add up to 100)')
+
+if __name__ == '__main__':
+  args = argp.parse_args()
+
+  test_settings = TestSettings(
+      args.build_docker_image, args.test_poll_interval_secs,
+      args.test_duration_secs, args.kubernetes_proxy_port)
+
+  gke_settings = GkeSettings(args.project_id, args.docker_image_name)
+
+  stress_server_settings = StressServerSettings(_SERVER_POD_NAME,
+                                                args.stress_server_port)
+  stress_client_settings = StressClientSettings(
+      args.num_clients, _CLIENT_POD_NAME_PREFIX, _SERVER_POD_NAME,
+      args.stress_server_port, args.stress_client_metrics_port,
+      args.stress_client_metrics_collection_interval_secs,
+      args.stress_client_poll_interval_secs,
+      args.stress_client_num_channels_per_server,
+      args.stress_client_num_stubs_per_channel, args.stress_client_test_cases)
+
+  run_test_main(test_settings, gke_settings, stress_server_settings,
+                stress_client_settings)
diff --git a/tools/run_tests/tests.json b/tools/run_tests/tests.json
index ea9c129..d91245c 100644
--- a/tools/run_tests/tests.json
+++ b/tools/run_tests/tests.json
@@ -12,6 +12,7 @@
     "cpu_cost": 1.0, 
     "exclude_configs": [], 
     "flaky": false, 
+    "gtest": false, 
     "language": "c", 
     "name": "alarm_test", 
     "platforms": [
@@ -32,6 +33,7 @@
     "cpu_cost": 1.0, 
     "exclude_configs": [], 
     "flaky": false, 
+    "gtest": false, 
     "language": "c", 
     "name": "algorithm_test", 
     "platforms": [
@@ -52,6 +54,7 @@
     "cpu_cost": 1.0, 
     "exclude_configs": [], 
     "flaky": false, 
+    "gtest": false, 
     "language": "c", 
     "name": "alloc_test", 
     "platforms": [
@@ -72,6 +75,7 @@
     "cpu_cost": 1.0, 
     "exclude_configs": [], 
     "flaky": false, 
+    "gtest": false, 
     "language": "c", 
     "name": "alpn_test", 
     "platforms": [
@@ -92,6 +96,7 @@
     "cpu_cost": 1.0, 
     "exclude_configs": [], 
     "flaky": false, 
+    "gtest": false, 
     "language": "c", 
     "name": "bin_encoder_test", 
     "platforms": [
@@ -112,6 +117,7 @@
     "cpu_cost": 1.0, 
     "exclude_configs": [], 
     "flaky": false, 
+    "gtest": false, 
     "language": "c", 
     "name": "census_context_test", 
     "platforms": [
@@ -132,26 +138,7 @@
     "cpu_cost": 1.0, 
     "exclude_configs": [], 
     "flaky": false, 
-    "language": "c", 
-    "name": "census_log_test", 
-    "platforms": [
-      "linux", 
-      "mac", 
-      "posix", 
-      "windows"
-    ]
-  }, 
-  {
-    "args": [], 
-    "ci_platforms": [
-      "linux", 
-      "mac", 
-      "posix", 
-      "windows"
-    ], 
-    "cpu_cost": 1.0, 
-    "exclude_configs": [], 
-    "flaky": false, 
+    "gtest": false, 
     "language": "c", 
     "name": "channel_create_test", 
     "platforms": [
@@ -172,6 +159,7 @@
     "cpu_cost": 1.0, 
     "exclude_configs": [], 
     "flaky": false, 
+    "gtest": false, 
     "language": "c", 
     "name": "chttp2_hpack_encoder_test", 
     "platforms": [
@@ -192,6 +180,7 @@
     "cpu_cost": 1.0, 
     "exclude_configs": [], 
     "flaky": false, 
+    "gtest": false, 
     "language": "c", 
     "name": "chttp2_status_conversion_test", 
     "platforms": [
@@ -212,6 +201,7 @@
     "cpu_cost": 1.0, 
     "exclude_configs": [], 
     "flaky": false, 
+    "gtest": false, 
     "language": "c", 
     "name": "chttp2_stream_map_test", 
     "platforms": [
@@ -232,6 +222,7 @@
     "cpu_cost": 1.0, 
     "exclude_configs": [], 
     "flaky": false, 
+    "gtest": false, 
     "language": "c", 
     "name": "chttp2_varint_test", 
     "platforms": [
@@ -252,6 +243,7 @@
     "cpu_cost": 1.0, 
     "exclude_configs": [], 
     "flaky": false, 
+    "gtest": false, 
     "language": "c", 
     "name": "compression_test", 
     "platforms": [
@@ -272,6 +264,7 @@
     "cpu_cost": 1.0, 
     "exclude_configs": [], 
     "flaky": false, 
+    "gtest": false, 
     "language": "c", 
     "name": "dns_resolver_test", 
     "platforms": [
@@ -291,6 +284,7 @@
     "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "flaky": false, 
+    "gtest": false, 
     "language": "c", 
     "name": "dualstack_socket_test", 
     "platforms": [
@@ -310,6 +304,7 @@
     "cpu_cost": 1.0, 
     "exclude_configs": [], 
     "flaky": false, 
+    "gtest": false, 
     "language": "c", 
     "name": "endpoint_pair_test", 
     "platforms": [
@@ -329,6 +324,7 @@
     "cpu_cost": 1.0, 
     "exclude_configs": [], 
     "flaky": false, 
+    "gtest": false, 
     "language": "c", 
     "name": "fd_conservation_posix_test", 
     "platforms": [
@@ -347,6 +343,7 @@
     "cpu_cost": 1.0, 
     "exclude_configs": [], 
     "flaky": false, 
+    "gtest": false, 
     "language": "c", 
     "name": "fd_posix_test", 
     "platforms": [
@@ -365,6 +362,7 @@
     "cpu_cost": 2, 
     "exclude_configs": [], 
     "flaky": false, 
+    "gtest": false, 
     "language": "c", 
     "name": "fling_stream_test", 
     "platforms": [
@@ -383,6 +381,7 @@
     "cpu_cost": 2, 
     "exclude_configs": [], 
     "flaky": false, 
+    "gtest": false, 
     "language": "c", 
     "name": "fling_test", 
     "platforms": [
@@ -402,6 +401,7 @@
     "cpu_cost": 1.0, 
     "exclude_configs": [], 
     "flaky": false, 
+    "gtest": false, 
     "language": "c", 
     "name": "gpr_avl_test", 
     "platforms": [
@@ -422,6 +422,7 @@
     "cpu_cost": 1.0, 
     "exclude_configs": [], 
     "flaky": false, 
+    "gtest": false, 
     "language": "c", 
     "name": "gpr_cmdline_test", 
     "platforms": [
@@ -442,6 +443,7 @@
     "cpu_cost": 1.0, 
     "exclude_configs": [], 
     "flaky": false, 
+    "gtest": false, 
     "language": "c", 
     "name": "gpr_cpu_test", 
     "platforms": [
@@ -462,6 +464,7 @@
     "cpu_cost": 1.0, 
     "exclude_configs": [], 
     "flaky": false, 
+    "gtest": false, 
     "language": "c", 
     "name": "gpr_env_test", 
     "platforms": [
@@ -482,26 +485,7 @@
     "cpu_cost": 1.0, 
     "exclude_configs": [], 
     "flaky": false, 
-    "language": "c", 
-    "name": "gpr_file_test", 
-    "platforms": [
-      "linux", 
-      "mac", 
-      "posix", 
-      "windows"
-    ]
-  }, 
-  {
-    "args": [], 
-    "ci_platforms": [
-      "linux", 
-      "mac", 
-      "posix", 
-      "windows"
-    ], 
-    "cpu_cost": 1.0, 
-    "exclude_configs": [], 
-    "flaky": false, 
+    "gtest": false, 
     "language": "c", 
     "name": "gpr_histogram_test", 
     "platforms": [
@@ -522,6 +506,7 @@
     "cpu_cost": 1.0, 
     "exclude_configs": [], 
     "flaky": false, 
+    "gtest": false, 
     "language": "c", 
     "name": "gpr_host_port_test", 
     "platforms": [
@@ -542,6 +527,28 @@
     "cpu_cost": 1.0, 
     "exclude_configs": [], 
     "flaky": false, 
+    "gtest": false, 
+    "language": "c", 
+    "name": "gpr_load_file_test", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ]
+  }, 
+  {
+    "args": [], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "gtest": false, 
     "language": "c", 
     "name": "gpr_log_test", 
     "platforms": [
@@ -562,6 +569,7 @@
     "cpu_cost": 1.0, 
     "exclude_configs": [], 
     "flaky": false, 
+    "gtest": false, 
     "language": "c", 
     "name": "gpr_slice_buffer_test", 
     "platforms": [
@@ -582,6 +590,7 @@
     "cpu_cost": 1.0, 
     "exclude_configs": [], 
     "flaky": false, 
+    "gtest": false, 
     "language": "c", 
     "name": "gpr_slice_test", 
     "platforms": [
@@ -602,6 +611,7 @@
     "cpu_cost": 10, 
     "exclude_configs": [], 
     "flaky": false, 
+    "gtest": false, 
     "language": "c", 
     "name": "gpr_stack_lockfree_test", 
     "platforms": [
@@ -622,6 +632,7 @@
     "cpu_cost": 1.0, 
     "exclude_configs": [], 
     "flaky": false, 
+    "gtest": false, 
     "language": "c", 
     "name": "gpr_string_test", 
     "platforms": [
@@ -642,6 +653,7 @@
     "cpu_cost": 10, 
     "exclude_configs": [], 
     "flaky": false, 
+    "gtest": false, 
     "language": "c", 
     "name": "gpr_sync_test", 
     "platforms": [
@@ -662,6 +674,7 @@
     "cpu_cost": 10, 
     "exclude_configs": [], 
     "flaky": false, 
+    "gtest": false, 
     "language": "c", 
     "name": "gpr_thd_test", 
     "platforms": [
@@ -682,6 +695,7 @@
     "cpu_cost": 1.0, 
     "exclude_configs": [], 
     "flaky": false, 
+    "gtest": false, 
     "language": "c", 
     "name": "gpr_time_test", 
     "platforms": [
@@ -702,6 +716,7 @@
     "cpu_cost": 1.0, 
     "exclude_configs": [], 
     "flaky": false, 
+    "gtest": false, 
     "language": "c", 
     "name": "gpr_tls_test", 
     "platforms": [
@@ -722,6 +737,7 @@
     "cpu_cost": 1.0, 
     "exclude_configs": [], 
     "flaky": false, 
+    "gtest": false, 
     "language": "c", 
     "name": "gpr_useful_test", 
     "platforms": [
@@ -742,6 +758,7 @@
     "cpu_cost": 1.0, 
     "exclude_configs": [], 
     "flaky": false, 
+    "gtest": false, 
     "language": "c", 
     "name": "grpc_auth_context_test", 
     "platforms": [
@@ -762,8 +779,9 @@
     "cpu_cost": 1.0, 
     "exclude_configs": [], 
     "flaky": false, 
+    "gtest": false, 
     "language": "c", 
-    "name": "grpc_base64_test", 
+    "name": "grpc_b64_test", 
     "platforms": [
       "linux", 
       "mac", 
@@ -782,6 +800,7 @@
     "cpu_cost": 1.0, 
     "exclude_configs": [], 
     "flaky": false, 
+    "gtest": false, 
     "language": "c", 
     "name": "grpc_byte_buffer_reader_test", 
     "platforms": [
@@ -802,6 +821,7 @@
     "cpu_cost": 1.0, 
     "exclude_configs": [], 
     "flaky": false, 
+    "gtest": false, 
     "language": "c", 
     "name": "grpc_channel_args_test", 
     "platforms": [
@@ -822,6 +842,7 @@
     "cpu_cost": 1.0, 
     "exclude_configs": [], 
     "flaky": false, 
+    "gtest": false, 
     "language": "c", 
     "name": "grpc_channel_stack_test", 
     "platforms": [
@@ -842,6 +863,7 @@
     "cpu_cost": 1.0, 
     "exclude_configs": [], 
     "flaky": false, 
+    "gtest": false, 
     "language": "c", 
     "name": "grpc_completion_queue_test", 
     "platforms": [
@@ -862,6 +884,7 @@
     "cpu_cost": 1.0, 
     "exclude_configs": [], 
     "flaky": false, 
+    "gtest": false, 
     "language": "c", 
     "name": "grpc_credentials_test", 
     "platforms": [
@@ -882,6 +905,7 @@
     "cpu_cost": 1.0, 
     "exclude_configs": [], 
     "flaky": false, 
+    "gtest": false, 
     "language": "c", 
     "name": "grpc_invalid_channel_args_test", 
     "platforms": [
@@ -901,6 +925,7 @@
     "cpu_cost": 1.0, 
     "exclude_configs": [], 
     "flaky": false, 
+    "gtest": false, 
     "language": "c", 
     "name": "grpc_json_token_test", 
     "platforms": [
@@ -920,6 +945,7 @@
     "cpu_cost": 1.0, 
     "exclude_configs": [], 
     "flaky": false, 
+    "gtest": false, 
     "language": "c", 
     "name": "grpc_jwt_verifier_test", 
     "platforms": [
@@ -940,6 +966,7 @@
     "cpu_cost": 1.0, 
     "exclude_configs": [], 
     "flaky": false, 
+    "gtest": false, 
     "language": "c", 
     "name": "grpc_security_connector_test", 
     "platforms": [
@@ -960,6 +987,7 @@
     "cpu_cost": 1.0, 
     "exclude_configs": [], 
     "flaky": false, 
+    "gtest": false, 
     "language": "c", 
     "name": "hpack_parser_test", 
     "platforms": [
@@ -980,6 +1008,7 @@
     "cpu_cost": 1.0, 
     "exclude_configs": [], 
     "flaky": false, 
+    "gtest": false, 
     "language": "c", 
     "name": "hpack_table_test", 
     "platforms": [
@@ -1000,6 +1029,7 @@
     "cpu_cost": 1.0, 
     "exclude_configs": [], 
     "flaky": false, 
+    "gtest": false, 
     "language": "c", 
     "name": "httpcli_format_request_test", 
     "platforms": [
@@ -1020,6 +1050,7 @@
     "cpu_cost": 1.0, 
     "exclude_configs": [], 
     "flaky": false, 
+    "gtest": false, 
     "language": "c", 
     "name": "httpcli_parser_test", 
     "platforms": [
@@ -1039,6 +1070,7 @@
     "cpu_cost": 0.5, 
     "exclude_configs": [], 
     "flaky": false, 
+    "gtest": false, 
     "language": "c", 
     "name": "httpcli_test", 
     "platforms": [
@@ -1055,6 +1087,7 @@
     "cpu_cost": 0.5, 
     "exclude_configs": [], 
     "flaky": false, 
+    "gtest": false, 
     "language": "c", 
     "name": "httpscli_test", 
     "platforms": [
@@ -1072,6 +1105,7 @@
     "cpu_cost": 1.0, 
     "exclude_configs": [], 
     "flaky": false, 
+    "gtest": false, 
     "language": "c", 
     "name": "init_test", 
     "platforms": [
@@ -1092,6 +1126,7 @@
     "cpu_cost": 1.0, 
     "exclude_configs": [], 
     "flaky": false, 
+    "gtest": false, 
     "language": "c", 
     "name": "invalid_call_argument_test", 
     "platforms": [
@@ -1112,6 +1147,7 @@
     "cpu_cost": 1.0, 
     "exclude_configs": [], 
     "flaky": false, 
+    "gtest": false, 
     "language": "c", 
     "name": "json_rewrite_test", 
     "platforms": [
@@ -1132,6 +1168,7 @@
     "cpu_cost": 1.0, 
     "exclude_configs": [], 
     "flaky": false, 
+    "gtest": false, 
     "language": "c", 
     "name": "json_stream_error_test", 
     "platforms": [
@@ -1152,6 +1189,7 @@
     "cpu_cost": 1.0, 
     "exclude_configs": [], 
     "flaky": false, 
+    "gtest": false, 
     "language": "c", 
     "name": "json_test", 
     "platforms": [
@@ -1172,6 +1210,7 @@
     "cpu_cost": 1.0, 
     "exclude_configs": [], 
     "flaky": false, 
+    "gtest": false, 
     "language": "c", 
     "name": "lame_client_test", 
     "platforms": [
@@ -1192,6 +1231,7 @@
     "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "flaky": false, 
+    "gtest": false, 
     "language": "c", 
     "name": "lb_policies_test", 
     "platforms": [
@@ -1212,6 +1252,7 @@
     "cpu_cost": 1.0, 
     "exclude_configs": [], 
     "flaky": false, 
+    "gtest": false, 
     "language": "c", 
     "name": "message_compress_test", 
     "platforms": [
@@ -1232,6 +1273,28 @@
     "cpu_cost": 1.0, 
     "exclude_configs": [], 
     "flaky": false, 
+    "gtest": false, 
+    "language": "c", 
+    "name": "mlog_test", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ]
+  }, 
+  {
+    "args": [], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "gtest": false, 
     "language": "c", 
     "name": "multiple_server_queues_test", 
     "platforms": [
@@ -1252,6 +1315,7 @@
     "cpu_cost": 1.0, 
     "exclude_configs": [], 
     "flaky": false, 
+    "gtest": false, 
     "language": "c", 
     "name": "murmur_hash_test", 
     "platforms": [
@@ -1272,6 +1336,7 @@
     "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "flaky": false, 
+    "gtest": false, 
     "language": "c", 
     "name": "no_server_test", 
     "platforms": [
@@ -1292,6 +1357,7 @@
     "cpu_cost": 1.0, 
     "exclude_configs": [], 
     "flaky": false, 
+    "gtest": false, 
     "language": "c", 
     "name": "resolve_address_test", 
     "platforms": [
@@ -1312,6 +1378,7 @@
     "cpu_cost": 1.0, 
     "exclude_configs": [], 
     "flaky": false, 
+    "gtest": false, 
     "language": "c", 
     "name": "secure_channel_create_test", 
     "platforms": [
@@ -1332,6 +1399,7 @@
     "cpu_cost": 1.0, 
     "exclude_configs": [], 
     "flaky": false, 
+    "gtest": false, 
     "language": "c", 
     "name": "secure_endpoint_test", 
     "platforms": [
@@ -1352,6 +1420,7 @@
     "cpu_cost": 1.0, 
     "exclude_configs": [], 
     "flaky": false, 
+    "gtest": false, 
     "language": "c", 
     "name": "server_chttp2_test", 
     "platforms": [
@@ -1372,6 +1441,7 @@
     "cpu_cost": 1.0, 
     "exclude_configs": [], 
     "flaky": false, 
+    "gtest": false, 
     "language": "c", 
     "name": "server_test", 
     "platforms": [
@@ -1392,6 +1462,7 @@
     "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "flaky": false, 
+    "gtest": false, 
     "language": "c", 
     "name": "set_initial_connect_string_test", 
     "platforms": [
@@ -1412,6 +1483,7 @@
     "cpu_cost": 1.0, 
     "exclude_configs": [], 
     "flaky": false, 
+    "gtest": false, 
     "language": "c", 
     "name": "sockaddr_resolver_test", 
     "platforms": [
@@ -1432,6 +1504,7 @@
     "cpu_cost": 1.0, 
     "exclude_configs": [], 
     "flaky": false, 
+    "gtest": false, 
     "language": "c", 
     "name": "sockaddr_utils_test", 
     "platforms": [
@@ -1451,6 +1524,7 @@
     "cpu_cost": 1.0, 
     "exclude_configs": [], 
     "flaky": false, 
+    "gtest": false, 
     "language": "c", 
     "name": "socket_utils_test", 
     "platforms": [
@@ -1469,6 +1543,7 @@
     "cpu_cost": 0.5, 
     "exclude_configs": [], 
     "flaky": false, 
+    "gtest": false, 
     "language": "c", 
     "name": "tcp_client_posix_test", 
     "platforms": [
@@ -1487,6 +1562,7 @@
     "cpu_cost": 0.5, 
     "exclude_configs": [], 
     "flaky": false, 
+    "gtest": false, 
     "language": "c", 
     "name": "tcp_posix_test", 
     "platforms": [
@@ -1505,6 +1581,7 @@
     "cpu_cost": 1.0, 
     "exclude_configs": [], 
     "flaky": false, 
+    "gtest": false, 
     "language": "c", 
     "name": "tcp_server_posix_test", 
     "platforms": [
@@ -1524,6 +1601,7 @@
     "cpu_cost": 1.0, 
     "exclude_configs": [], 
     "flaky": false, 
+    "gtest": false, 
     "language": "c", 
     "name": "time_averaged_stats_test", 
     "platforms": [
@@ -1544,6 +1622,7 @@
     "cpu_cost": 1.0, 
     "exclude_configs": [], 
     "flaky": false, 
+    "gtest": false, 
     "language": "c", 
     "name": "timeout_encoding_test", 
     "platforms": [
@@ -1564,6 +1643,7 @@
     "cpu_cost": 1.0, 
     "exclude_configs": [], 
     "flaky": false, 
+    "gtest": false, 
     "language": "c", 
     "name": "timer_heap_test", 
     "platforms": [
@@ -1584,6 +1664,7 @@
     "cpu_cost": 1.0, 
     "exclude_configs": [], 
     "flaky": false, 
+    "gtest": false, 
     "language": "c", 
     "name": "timer_list_test", 
     "platforms": [
@@ -1604,6 +1685,7 @@
     "cpu_cost": 1.0, 
     "exclude_configs": [], 
     "flaky": false, 
+    "gtest": false, 
     "language": "c", 
     "name": "timers_test", 
     "platforms": [
@@ -1624,6 +1706,7 @@
     "cpu_cost": 1.0, 
     "exclude_configs": [], 
     "flaky": false, 
+    "gtest": false, 
     "language": "c", 
     "name": "transport_connectivity_state_test", 
     "platforms": [
@@ -1644,6 +1727,7 @@
     "cpu_cost": 1.0, 
     "exclude_configs": [], 
     "flaky": false, 
+    "gtest": false, 
     "language": "c", 
     "name": "transport_metadata_test", 
     "platforms": [
@@ -1663,6 +1747,7 @@
     "cpu_cost": 1.0, 
     "exclude_configs": [], 
     "flaky": false, 
+    "gtest": false, 
     "language": "c", 
     "name": "transport_security_test", 
     "platforms": [
@@ -1681,6 +1766,7 @@
     "cpu_cost": 1.0, 
     "exclude_configs": [], 
     "flaky": false, 
+    "gtest": false, 
     "language": "c", 
     "name": "udp_server_test", 
     "platforms": [
@@ -1700,6 +1786,7 @@
     "cpu_cost": 1.0, 
     "exclude_configs": [], 
     "flaky": false, 
+    "gtest": false, 
     "language": "c", 
     "name": "uri_parser_test", 
     "platforms": [
@@ -1719,6 +1806,7 @@
     "cpu_cost": 1.0, 
     "exclude_configs": [], 
     "flaky": false, 
+    "gtest": false, 
     "language": "c", 
     "name": "workqueue_test", 
     "platforms": [
@@ -1738,6 +1826,7 @@
     "cpu_cost": 1.0, 
     "exclude_configs": [], 
     "flaky": false, 
+    "gtest": true, 
     "language": "c++", 
     "name": "alarm_cpp_test", 
     "platforms": [
@@ -1758,6 +1847,7 @@
     "cpu_cost": 1.0, 
     "exclude_configs": [], 
     "flaky": false, 
+    "gtest": true, 
     "language": "c++", 
     "name": "async_end2end_test", 
     "platforms": [
@@ -1777,6 +1867,7 @@
     "cpu_cost": 1.0, 
     "exclude_configs": [], 
     "flaky": false, 
+    "gtest": false, 
     "language": "c++", 
     "name": "async_streaming_ping_pong_test", 
     "platforms": [
@@ -1795,6 +1886,7 @@
     "cpu_cost": 1.0, 
     "exclude_configs": [], 
     "flaky": false, 
+    "gtest": false, 
     "language": "c++", 
     "name": "async_unary_ping_pong_test", 
     "platforms": [
@@ -1814,6 +1906,7 @@
     "cpu_cost": 1.0, 
     "exclude_configs": [], 
     "flaky": false, 
+    "gtest": true, 
     "language": "c++", 
     "name": "auth_property_iterator_test", 
     "platforms": [
@@ -1834,6 +1927,7 @@
     "cpu_cost": 1.0, 
     "exclude_configs": [], 
     "flaky": false, 
+    "gtest": true, 
     "language": "c++", 
     "name": "channel_arguments_test", 
     "platforms": [
@@ -1854,6 +1948,7 @@
     "cpu_cost": 1.0, 
     "exclude_configs": [], 
     "flaky": false, 
+    "gtest": true, 
     "language": "c++", 
     "name": "cli_call_test", 
     "platforms": [
@@ -1873,6 +1968,7 @@
     "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "flaky": false, 
+    "gtest": true, 
     "language": "c++", 
     "name": "client_crash_test", 
     "platforms": [
@@ -1892,6 +1988,7 @@
     "cpu_cost": 1.0, 
     "exclude_configs": [], 
     "flaky": false, 
+    "gtest": true, 
     "language": "c++", 
     "name": "credentials_test", 
     "platforms": [
@@ -1912,6 +2009,7 @@
     "cpu_cost": 1.0, 
     "exclude_configs": [], 
     "flaky": false, 
+    "gtest": true, 
     "language": "c++", 
     "name": "cxx_byte_buffer_test", 
     "platforms": [
@@ -1932,6 +2030,7 @@
     "cpu_cost": 1.0, 
     "exclude_configs": [], 
     "flaky": false, 
+    "gtest": true, 
     "language": "c++", 
     "name": "cxx_slice_test", 
     "platforms": [
@@ -1952,6 +2051,7 @@
     "cpu_cost": 1.0, 
     "exclude_configs": [], 
     "flaky": false, 
+    "gtest": true, 
     "language": "c++", 
     "name": "cxx_string_ref_test", 
     "platforms": [
@@ -1972,6 +2072,7 @@
     "cpu_cost": 1.0, 
     "exclude_configs": [], 
     "flaky": false, 
+    "gtest": true, 
     "language": "c++", 
     "name": "cxx_time_test", 
     "platforms": [
@@ -1992,6 +2093,7 @@
     "cpu_cost": 0.5, 
     "exclude_configs": [], 
     "flaky": false, 
+    "gtest": true, 
     "language": "c++", 
     "name": "end2end_test", 
     "platforms": [
@@ -2011,6 +2113,7 @@
     "cpu_cost": 1.0, 
     "exclude_configs": [], 
     "flaky": false, 
+    "gtest": false, 
     "language": "c++", 
     "name": "generic_async_streaming_ping_pong_test", 
     "platforms": [
@@ -2030,6 +2133,7 @@
     "cpu_cost": 1.0, 
     "exclude_configs": [], 
     "flaky": false, 
+    "gtest": true, 
     "language": "c++", 
     "name": "generic_end2end_test", 
     "platforms": [
@@ -2050,6 +2154,28 @@
     "cpu_cost": 1.0, 
     "exclude_configs": [], 
     "flaky": false, 
+    "gtest": true, 
+    "language": "c++", 
+    "name": "grpclb_api_test", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ]
+  }, 
+  {
+    "args": [], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "gtest": true, 
     "language": "c++", 
     "name": "hybrid_end2end_test", 
     "platforms": [
@@ -2069,6 +2195,7 @@
     "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "flaky": false, 
+    "gtest": false, 
     "language": "c++", 
     "name": "interop_test", 
     "platforms": [
@@ -2088,6 +2215,7 @@
     "cpu_cost": 1.0, 
     "exclude_configs": [], 
     "flaky": false, 
+    "gtest": true, 
     "language": "c++", 
     "name": "mock_test", 
     "platforms": [
@@ -2104,9 +2232,10 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 1.0, 
+    "cpu_cost": 10, 
     "exclude_configs": [], 
     "flaky": false, 
+    "gtest": false, 
     "language": "c++", 
     "name": "qps_openloop_test", 
     "platforms": [
@@ -2123,10 +2252,9 @@
       "posix"
     ], 
     "cpu_cost": 10, 
-    "exclude_configs": [
-      "tsan"
-    ], 
+    "exclude_configs": [], 
     "flaky": false, 
+    "gtest": false, 
     "language": "c++", 
     "name": "qps_test", 
     "platforms": [
@@ -2146,6 +2274,7 @@
     "cpu_cost": 1.0, 
     "exclude_configs": [], 
     "flaky": false, 
+    "gtest": true, 
     "language": "c++", 
     "name": "secure_auth_context_test", 
     "platforms": [
@@ -2165,6 +2294,7 @@
     "cpu_cost": 1.0, 
     "exclude_configs": [], 
     "flaky": false, 
+    "gtest": false, 
     "language": "c++", 
     "name": "secure_sync_unary_ping_pong_test", 
     "platforms": [
@@ -2183,6 +2313,7 @@
     "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "flaky": false, 
+    "gtest": true, 
     "language": "c++", 
     "name": "server_crash_test", 
     "platforms": [
@@ -2202,6 +2333,7 @@
     "cpu_cost": 1.0, 
     "exclude_configs": [], 
     "flaky": false, 
+    "gtest": true, 
     "language": "c++", 
     "name": "shutdown_test", 
     "platforms": [
@@ -2222,6 +2354,7 @@
     "cpu_cost": 1.0, 
     "exclude_configs": [], 
     "flaky": false, 
+    "gtest": false, 
     "language": "c++", 
     "name": "status_test", 
     "platforms": [
@@ -2241,6 +2374,7 @@
     "cpu_cost": 1.0, 
     "exclude_configs": [], 
     "flaky": false, 
+    "gtest": true, 
     "language": "c++", 
     "name": "streaming_throughput_test", 
     "platforms": [
@@ -2259,6 +2393,7 @@
     "cpu_cost": 1.0, 
     "exclude_configs": [], 
     "flaky": false, 
+    "gtest": false, 
     "language": "c++", 
     "name": "sync_streaming_ping_pong_test", 
     "platforms": [
@@ -2277,6 +2412,7 @@
     "cpu_cost": 1.0, 
     "exclude_configs": [], 
     "flaky": false, 
+    "gtest": false, 
     "language": "c++", 
     "name": "sync_unary_ping_pong_test", 
     "platforms": [
@@ -2296,6 +2432,7 @@
     "cpu_cost": 100, 
     "exclude_configs": [], 
     "flaky": false, 
+    "gtest": true, 
     "language": "c++", 
     "name": "thread_stress_test", 
     "platforms": [
@@ -2316,6 +2453,7 @@
     "cpu_cost": 1.0, 
     "exclude_configs": [], 
     "flaky": false, 
+    "gtest": false, 
     "language": "c89", 
     "name": "public_headers_must_be_c89", 
     "platforms": [
@@ -2336,6 +2474,7 @@
     "cpu_cost": 1.0, 
     "exclude_configs": [], 
     "flaky": false, 
+    "gtest": false, 
     "language": "c", 
     "name": "badreq_bad_client_test", 
     "platforms": [
@@ -2356,6 +2495,7 @@
     "cpu_cost": 0.2, 
     "exclude_configs": [], 
     "flaky": false, 
+    "gtest": false, 
     "language": "c", 
     "name": "connection_prefix_bad_client_test", 
     "platforms": [
@@ -2376,6 +2516,7 @@
     "cpu_cost": 0.2, 
     "exclude_configs": [], 
     "flaky": false, 
+    "gtest": false, 
     "language": "c", 
     "name": "headers_bad_client_test", 
     "platforms": [
@@ -2396,6 +2537,7 @@
     "cpu_cost": 0.2, 
     "exclude_configs": [], 
     "flaky": false, 
+    "gtest": false, 
     "language": "c", 
     "name": "initial_settings_frame_bad_client_test", 
     "platforms": [
@@ -2416,6 +2558,7 @@
     "cpu_cost": 1.0, 
     "exclude_configs": [], 
     "flaky": false, 
+    "gtest": false, 
     "language": "c", 
     "name": "server_registered_method_bad_client_test", 
     "platforms": [
@@ -2436,6 +2579,7 @@
     "cpu_cost": 1.0, 
     "exclude_configs": [], 
     "flaky": false, 
+    "gtest": false, 
     "language": "c", 
     "name": "simple_request_bad_client_test", 
     "platforms": [
@@ -2456,6 +2600,7 @@
     "cpu_cost": 1.0, 
     "exclude_configs": [], 
     "flaky": false, 
+    "gtest": false, 
     "language": "c", 
     "name": "unknown_frame_bad_client_test", 
     "platforms": [
@@ -2476,6 +2621,7 @@
     "cpu_cost": 1.0, 
     "exclude_configs": [], 
     "flaky": false, 
+    "gtest": false, 
     "language": "c", 
     "name": "window_overflow_bad_client_test", 
     "platforms": [
@@ -2495,6 +2641,7 @@
     "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "flaky": false, 
+    "gtest": false, 
     "language": "c", 
     "name": "bad_ssl_alpn_test", 
     "platforms": [
@@ -2513,6 +2660,7 @@
     "cpu_cost": 0.1, 
     "exclude_configs": [], 
     "flaky": false, 
+    "gtest": false, 
     "language": "c", 
     "name": "bad_ssl_cert_test", 
     "platforms": [
@@ -4219,7 +4367,7 @@
   }, 
   {
     "args": [
-      "channel_connectivity"
+      "compressed_payload"
     ], 
     "ci_platforms": [
       "windows", 
@@ -4241,29 +4389,7 @@
   }, 
   {
     "args": [
-      "channel_ping"
-    ], 
-    "ci_platforms": [
-      "windows", 
-      "linux", 
-      "mac", 
-      "posix"
-    ], 
-    "cpu_cost": 1.0, 
-    "exclude_configs": [], 
-    "flaky": false, 
-    "language": "c", 
-    "name": "h2_census_test", 
-    "platforms": [
-      "windows", 
-      "linux", 
-      "mac", 
-      "posix"
-    ]
-  }, 
-  {
-    "args": [
-      "compressed_payload"
+      "connectivity"
     ], 
     "ci_platforms": [
       "windows", 
@@ -4505,28 +4631,6 @@
   }, 
   {
     "args": [
-      "metadata"
-    ], 
-    "ci_platforms": [
-      "windows", 
-      "linux", 
-      "mac", 
-      "posix"
-    ], 
-    "cpu_cost": 1.0, 
-    "exclude_configs": [], 
-    "flaky": false, 
-    "language": "c", 
-    "name": "h2_census_test", 
-    "platforms": [
-      "windows", 
-      "linux", 
-      "mac", 
-      "posix"
-    ]
-  }, 
-  {
-    "args": [
       "negative_deadline"
     ], 
     "ci_platforms": [
@@ -4593,6 +4697,28 @@
   }, 
   {
     "args": [
+      "ping"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_census_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "ping_pong_streaming"
     ], 
     "ci_platforms": [
@@ -4769,6 +4895,28 @@
   }, 
   {
     "args": [
+      "simple_metadata"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_census_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "simple_request"
     ], 
     "ci_platforms": [
@@ -5011,7 +5159,7 @@
   }, 
   {
     "args": [
-      "channel_connectivity"
+      "compressed_payload"
     ], 
     "ci_platforms": [
       "windows", 
@@ -5033,29 +5181,7 @@
   }, 
   {
     "args": [
-      "channel_ping"
-    ], 
-    "ci_platforms": [
-      "windows", 
-      "linux", 
-      "mac", 
-      "posix"
-    ], 
-    "cpu_cost": 1.0, 
-    "exclude_configs": [], 
-    "flaky": false, 
-    "language": "c", 
-    "name": "h2_compress_test", 
-    "platforms": [
-      "windows", 
-      "linux", 
-      "mac", 
-      "posix"
-    ]
-  }, 
-  {
-    "args": [
-      "compressed_payload"
+      "connectivity"
     ], 
     "ci_platforms": [
       "windows", 
@@ -5297,28 +5423,6 @@
   }, 
   {
     "args": [
-      "metadata"
-    ], 
-    "ci_platforms": [
-      "windows", 
-      "linux", 
-      "mac", 
-      "posix"
-    ], 
-    "cpu_cost": 1.0, 
-    "exclude_configs": [], 
-    "flaky": false, 
-    "language": "c", 
-    "name": "h2_compress_test", 
-    "platforms": [
-      "windows", 
-      "linux", 
-      "mac", 
-      "posix"
-    ]
-  }, 
-  {
-    "args": [
       "negative_deadline"
     ], 
     "ci_platforms": [
@@ -5385,6 +5489,28 @@
   }, 
   {
     "args": [
+      "ping"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_compress_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "ping_pong_streaming"
     ], 
     "ci_platforms": [
@@ -5561,6 +5687,28 @@
   }, 
   {
     "args": [
+      "simple_metadata"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_compress_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "simple_request"
     ], 
     "ci_platforms": [
@@ -5794,7 +5942,7 @@
   }, 
   {
     "args": [
-      "channel_connectivity"
+      "compressed_payload"
     ], 
     "ci_platforms": [
       "windows", 
@@ -5815,28 +5963,7 @@
   }, 
   {
     "args": [
-      "channel_ping"
-    ], 
-    "ci_platforms": [
-      "windows", 
-      "linux", 
-      "posix"
-    ], 
-    "cpu_cost": 1.0, 
-    "exclude_configs": [], 
-    "flaky": false, 
-    "language": "c", 
-    "name": "h2_fakesec_test", 
-    "platforms": [
-      "windows", 
-      "linux", 
-      "mac", 
-      "posix"
-    ]
-  }, 
-  {
-    "args": [
-      "compressed_payload"
+      "connectivity"
     ], 
     "ci_platforms": [
       "windows", 
@@ -6067,27 +6194,6 @@
   }, 
   {
     "args": [
-      "metadata"
-    ], 
-    "ci_platforms": [
-      "windows", 
-      "linux", 
-      "posix"
-    ], 
-    "cpu_cost": 1.0, 
-    "exclude_configs": [], 
-    "flaky": false, 
-    "language": "c", 
-    "name": "h2_fakesec_test", 
-    "platforms": [
-      "windows", 
-      "linux", 
-      "mac", 
-      "posix"
-    ]
-  }, 
-  {
-    "args": [
       "negative_deadline"
     ], 
     "ci_platforms": [
@@ -6151,6 +6257,27 @@
   }, 
   {
     "args": [
+      "ping"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_fakesec_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "ping_pong_streaming"
     ], 
     "ci_platforms": [
@@ -6319,6 +6446,27 @@
   }, 
   {
     "args": [
+      "simple_metadata"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_fakesec_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "simple_request"
     ], 
     "ci_platforms": [
@@ -6559,7 +6707,7 @@
   }, 
   {
     "args": [
-      "channel_connectivity"
+      "compressed_payload"
     ], 
     "ci_platforms": [
       "windows", 
@@ -6581,29 +6729,7 @@
   }, 
   {
     "args": [
-      "channel_ping"
-    ], 
-    "ci_platforms": [
-      "windows", 
-      "linux", 
-      "mac", 
-      "posix"
-    ], 
-    "cpu_cost": 1.0, 
-    "exclude_configs": [], 
-    "flaky": false, 
-    "language": "c", 
-    "name": "h2_full_test", 
-    "platforms": [
-      "windows", 
-      "linux", 
-      "mac", 
-      "posix"
-    ]
-  }, 
-  {
-    "args": [
-      "compressed_payload"
+      "connectivity"
     ], 
     "ci_platforms": [
       "windows", 
@@ -6845,28 +6971,6 @@
   }, 
   {
     "args": [
-      "metadata"
-    ], 
-    "ci_platforms": [
-      "windows", 
-      "linux", 
-      "mac", 
-      "posix"
-    ], 
-    "cpu_cost": 1.0, 
-    "exclude_configs": [], 
-    "flaky": false, 
-    "language": "c", 
-    "name": "h2_full_test", 
-    "platforms": [
-      "windows", 
-      "linux", 
-      "mac", 
-      "posix"
-    ]
-  }, 
-  {
-    "args": [
       "negative_deadline"
     ], 
     "ci_platforms": [
@@ -6933,6 +7037,28 @@
   }, 
   {
     "args": [
+      "ping"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_full_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "ping_pong_streaming"
     ], 
     "ci_platforms": [
@@ -7109,6 +7235,28 @@
   }, 
   {
     "args": [
+      "simple_metadata"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_full_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "simple_request"
     ], 
     "ci_platforms": [
@@ -7297,7 +7445,7 @@
   }, 
   {
     "args": [
-      "channel_connectivity"
+      "compressed_payload"
     ], 
     "ci_platforms": [
       "linux"
@@ -7313,23 +7461,7 @@
   }, 
   {
     "args": [
-      "channel_ping"
-    ], 
-    "ci_platforms": [
-      "linux"
-    ], 
-    "cpu_cost": 1.0, 
-    "exclude_configs": [], 
-    "flaky": false, 
-    "language": "c", 
-    "name": "h2_full+pipe_test", 
-    "platforms": [
-      "linux"
-    ]
-  }, 
-  {
-    "args": [
-      "compressed_payload"
+      "connectivity"
     ], 
     "ci_platforms": [
       "linux"
@@ -7505,22 +7637,6 @@
   }, 
   {
     "args": [
-      "metadata"
-    ], 
-    "ci_platforms": [
-      "linux"
-    ], 
-    "cpu_cost": 1.0, 
-    "exclude_configs": [], 
-    "flaky": false, 
-    "language": "c", 
-    "name": "h2_full+pipe_test", 
-    "platforms": [
-      "linux"
-    ]
-  }, 
-  {
-    "args": [
       "negative_deadline"
     ], 
     "ci_platforms": [
@@ -7569,6 +7685,22 @@
   }, 
   {
     "args": [
+      "ping"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_full+pipe_test", 
+    "platforms": [
+      "linux"
+    ]
+  }, 
+  {
+    "args": [
       "ping_pong_streaming"
     ], 
     "ci_platforms": [
@@ -7697,6 +7829,22 @@
   }, 
   {
     "args": [
+      "simple_metadata"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_full+pipe_test", 
+    "platforms": [
+      "linux"
+    ]
+  }, 
+  {
+    "args": [
       "simple_request"
     ], 
     "ci_platforms": [
@@ -7873,7 +8021,7 @@
   }, 
   {
     "args": [
-      "channel_connectivity"
+      "compressed_payload"
     ], 
     "ci_platforms": [
       "linux"
@@ -7889,23 +8037,7 @@
   }, 
   {
     "args": [
-      "channel_ping"
-    ], 
-    "ci_platforms": [
-      "linux"
-    ], 
-    "cpu_cost": 1.0, 
-    "exclude_configs": [], 
-    "flaky": false, 
-    "language": "c", 
-    "name": "h2_full+poll_test", 
-    "platforms": [
-      "linux"
-    ]
-  }, 
-  {
-    "args": [
-      "compressed_payload"
+      "connectivity"
     ], 
     "ci_platforms": [
       "linux"
@@ -8081,22 +8213,6 @@
   }, 
   {
     "args": [
-      "metadata"
-    ], 
-    "ci_platforms": [
-      "linux"
-    ], 
-    "cpu_cost": 1.0, 
-    "exclude_configs": [], 
-    "flaky": false, 
-    "language": "c", 
-    "name": "h2_full+poll_test", 
-    "platforms": [
-      "linux"
-    ]
-  }, 
-  {
-    "args": [
       "negative_deadline"
     ], 
     "ci_platforms": [
@@ -8145,6 +8261,22 @@
   }, 
   {
     "args": [
+      "ping"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_full+poll_test", 
+    "platforms": [
+      "linux"
+    ]
+  }, 
+  {
+    "args": [
       "ping_pong_streaming"
     ], 
     "ci_platforms": [
@@ -8273,6 +8405,22 @@
   }, 
   {
     "args": [
+      "simple_metadata"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_full+poll_test", 
+    "platforms": [
+      "linux"
+    ]
+  }, 
+  {
+    "args": [
       "simple_request"
     ], 
     "ci_platforms": [
@@ -8449,7 +8597,7 @@
   }, 
   {
     "args": [
-      "channel_connectivity"
+      "compressed_payload"
     ], 
     "ci_platforms": [
       "linux"
@@ -8465,23 +8613,7 @@
   }, 
   {
     "args": [
-      "channel_ping"
-    ], 
-    "ci_platforms": [
-      "linux"
-    ], 
-    "cpu_cost": 1.0, 
-    "exclude_configs": [], 
-    "flaky": false, 
-    "language": "c", 
-    "name": "h2_full+poll+pipe_test", 
-    "platforms": [
-      "linux"
-    ]
-  }, 
-  {
-    "args": [
-      "compressed_payload"
+      "connectivity"
     ], 
     "ci_platforms": [
       "linux"
@@ -8657,22 +8789,6 @@
   }, 
   {
     "args": [
-      "metadata"
-    ], 
-    "ci_platforms": [
-      "linux"
-    ], 
-    "cpu_cost": 1.0, 
-    "exclude_configs": [], 
-    "flaky": false, 
-    "language": "c", 
-    "name": "h2_full+poll+pipe_test", 
-    "platforms": [
-      "linux"
-    ]
-  }, 
-  {
-    "args": [
       "negative_deadline"
     ], 
     "ci_platforms": [
@@ -8721,6 +8837,22 @@
   }, 
   {
     "args": [
+      "ping"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_full+poll+pipe_test", 
+    "platforms": [
+      "linux"
+    ]
+  }, 
+  {
+    "args": [
       "ping_pong_streaming"
     ], 
     "ci_platforms": [
@@ -8849,6 +8981,22 @@
   }, 
   {
     "args": [
+      "simple_metadata"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_full+poll+pipe_test", 
+    "platforms": [
+      "linux"
+    ]
+  }, 
+  {
+    "args": [
       "simple_request"
     ], 
     "ci_platforms": [
@@ -9070,7 +9218,7 @@
   }, 
   {
     "args": [
-      "channel_connectivity"
+      "compressed_payload"
     ], 
     "ci_platforms": [
       "windows", 
@@ -9091,28 +9239,7 @@
   }, 
   {
     "args": [
-      "channel_ping"
-    ], 
-    "ci_platforms": [
-      "windows", 
-      "linux", 
-      "posix"
-    ], 
-    "cpu_cost": 1.0, 
-    "exclude_configs": [], 
-    "flaky": false, 
-    "language": "c", 
-    "name": "h2_oauth2_test", 
-    "platforms": [
-      "windows", 
-      "linux", 
-      "mac", 
-      "posix"
-    ]
-  }, 
-  {
-    "args": [
-      "compressed_payload"
+      "connectivity"
     ], 
     "ci_platforms": [
       "windows", 
@@ -9343,27 +9470,6 @@
   }, 
   {
     "args": [
-      "metadata"
-    ], 
-    "ci_platforms": [
-      "windows", 
-      "linux", 
-      "posix"
-    ], 
-    "cpu_cost": 1.0, 
-    "exclude_configs": [], 
-    "flaky": false, 
-    "language": "c", 
-    "name": "h2_oauth2_test", 
-    "platforms": [
-      "windows", 
-      "linux", 
-      "mac", 
-      "posix"
-    ]
-  }, 
-  {
-    "args": [
       "negative_deadline"
     ], 
     "ci_platforms": [
@@ -9427,6 +9533,27 @@
   }, 
   {
     "args": [
+      "ping"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_oauth2_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "ping_pong_streaming"
     ], 
     "ci_platforms": [
@@ -9595,6 +9722,27 @@
   }, 
   {
     "args": [
+      "simple_metadata"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_oauth2_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "simple_request"
     ], 
     "ci_platforms": [
@@ -9994,27 +10142,6 @@
   }, 
   {
     "args": [
-      "metadata"
-    ], 
-    "ci_platforms": [
-      "windows", 
-      "linux", 
-      "posix"
-    ], 
-    "cpu_cost": 1.0, 
-    "exclude_configs": [], 
-    "flaky": false, 
-    "language": "c", 
-    "name": "h2_proxy_test", 
-    "platforms": [
-      "windows", 
-      "linux", 
-      "mac", 
-      "posix"
-    ]
-  }, 
-  {
-    "args": [
       "negative_deadline"
     ], 
     "ci_platforms": [
@@ -10225,6 +10352,27 @@
   }, 
   {
     "args": [
+      "simple_metadata"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_proxy_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "simple_request"
     ], 
     "ci_platforms": [
@@ -10645,27 +10793,6 @@
   }, 
   {
     "args": [
-      "metadata"
-    ], 
-    "ci_platforms": [
-      "windows", 
-      "linux", 
-      "posix"
-    ], 
-    "cpu_cost": 1.0, 
-    "exclude_configs": [], 
-    "flaky": false, 
-    "language": "c", 
-    "name": "h2_sockpair_test", 
-    "platforms": [
-      "windows", 
-      "linux", 
-      "mac", 
-      "posix"
-    ]
-  }, 
-  {
-    "args": [
       "negative_deadline"
     ], 
     "ci_platforms": [
@@ -10876,6 +11003,27 @@
   }, 
   {
     "args": [
+      "simple_metadata"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_sockpair_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "simple_request"
     ], 
     "ci_platforms": [
@@ -11292,28 +11440,6 @@
   }, 
   {
     "args": [
-      "metadata"
-    ], 
-    "ci_platforms": [
-      "windows", 
-      "linux", 
-      "mac", 
-      "posix"
-    ], 
-    "cpu_cost": 1.0, 
-    "exclude_configs": [], 
-    "flaky": false, 
-    "language": "c", 
-    "name": "h2_sockpair+trace_test", 
-    "platforms": [
-      "windows", 
-      "linux", 
-      "mac", 
-      "posix"
-    ]
-  }, 
-  {
-    "args": [
       "negative_deadline"
     ], 
     "ci_platforms": [
@@ -11534,6 +11660,28 @@
   }, 
   {
     "args": [
+      "simple_metadata"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_sockpair+trace_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "simple_request"
     ], 
     "ci_platforms": [
@@ -11956,27 +12104,6 @@
   }, 
   {
     "args": [
-      "metadata"
-    ], 
-    "ci_platforms": [
-      "windows", 
-      "linux", 
-      "posix"
-    ], 
-    "cpu_cost": 1.0, 
-    "exclude_configs": [], 
-    "flaky": false, 
-    "language": "c", 
-    "name": "h2_sockpair_1byte_test", 
-    "platforms": [
-      "windows", 
-      "linux", 
-      "mac", 
-      "posix"
-    ]
-  }, 
-  {
-    "args": [
       "negative_deadline"
     ], 
     "ci_platforms": [
@@ -12187,6 +12314,27 @@
   }, 
   {
     "args": [
+      "simple_metadata"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_sockpair_1byte_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "simple_request"
     ], 
     "ci_platforms": [
@@ -12427,7 +12575,7 @@
   }, 
   {
     "args": [
-      "channel_connectivity"
+      "compressed_payload"
     ], 
     "ci_platforms": [
       "windows", 
@@ -12449,29 +12597,7 @@
   }, 
   {
     "args": [
-      "channel_ping"
-    ], 
-    "ci_platforms": [
-      "windows", 
-      "linux", 
-      "mac", 
-      "posix"
-    ], 
-    "cpu_cost": 1.0, 
-    "exclude_configs": [], 
-    "flaky": false, 
-    "language": "c", 
-    "name": "h2_ssl_test", 
-    "platforms": [
-      "windows", 
-      "linux", 
-      "mac", 
-      "posix"
-    ]
-  }, 
-  {
-    "args": [
-      "compressed_payload"
+      "connectivity"
     ], 
     "ci_platforms": [
       "windows", 
@@ -12713,28 +12839,6 @@
   }, 
   {
     "args": [
-      "metadata"
-    ], 
-    "ci_platforms": [
-      "windows", 
-      "linux", 
-      "mac", 
-      "posix"
-    ], 
-    "cpu_cost": 1.0, 
-    "exclude_configs": [], 
-    "flaky": false, 
-    "language": "c", 
-    "name": "h2_ssl_test", 
-    "platforms": [
-      "windows", 
-      "linux", 
-      "mac", 
-      "posix"
-    ]
-  }, 
-  {
-    "args": [
       "negative_deadline"
     ], 
     "ci_platforms": [
@@ -12801,6 +12905,28 @@
   }, 
   {
     "args": [
+      "ping"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_ssl_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "ping_pong_streaming"
     ], 
     "ci_platforms": [
@@ -12977,6 +13103,28 @@
   }, 
   {
     "args": [
+      "simple_metadata"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_ssl_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "simple_request"
     ], 
     "ci_platforms": [
@@ -13165,7 +13313,7 @@
   }, 
   {
     "args": [
-      "channel_connectivity"
+      "compressed_payload"
     ], 
     "ci_platforms": [
       "linux"
@@ -13181,23 +13329,7 @@
   }, 
   {
     "args": [
-      "channel_ping"
-    ], 
-    "ci_platforms": [
-      "linux"
-    ], 
-    "cpu_cost": 1.0, 
-    "exclude_configs": [], 
-    "flaky": false, 
-    "language": "c", 
-    "name": "h2_ssl+poll_test", 
-    "platforms": [
-      "linux"
-    ]
-  }, 
-  {
-    "args": [
-      "compressed_payload"
+      "connectivity"
     ], 
     "ci_platforms": [
       "linux"
@@ -13373,22 +13505,6 @@
   }, 
   {
     "args": [
-      "metadata"
-    ], 
-    "ci_platforms": [
-      "linux"
-    ], 
-    "cpu_cost": 1.0, 
-    "exclude_configs": [], 
-    "flaky": false, 
-    "language": "c", 
-    "name": "h2_ssl+poll_test", 
-    "platforms": [
-      "linux"
-    ]
-  }, 
-  {
-    "args": [
       "negative_deadline"
     ], 
     "ci_platforms": [
@@ -13437,6 +13553,22 @@
   }, 
   {
     "args": [
+      "ping"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_ssl+poll_test", 
+    "platforms": [
+      "linux"
+    ]
+  }, 
+  {
+    "args": [
       "ping_pong_streaming"
     ], 
     "ci_platforms": [
@@ -13565,6 +13697,22 @@
   }, 
   {
     "args": [
+      "simple_metadata"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_ssl+poll_test", 
+    "platforms": [
+      "linux"
+    ]
+  }, 
+  {
+    "args": [
       "simple_request"
     ], 
     "ci_platforms": [
@@ -13954,27 +14102,6 @@
   }, 
   {
     "args": [
-      "metadata"
-    ], 
-    "ci_platforms": [
-      "windows", 
-      "linux", 
-      "posix"
-    ], 
-    "cpu_cost": 1.0, 
-    "exclude_configs": [], 
-    "flaky": false, 
-    "language": "c", 
-    "name": "h2_ssl_proxy_test", 
-    "platforms": [
-      "windows", 
-      "linux", 
-      "mac", 
-      "posix"
-    ]
-  }, 
-  {
-    "args": [
       "negative_deadline"
     ], 
     "ci_platforms": [
@@ -14185,6 +14312,27 @@
   }, 
   {
     "args": [
+      "simple_metadata"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_ssl_proxy_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "simple_request"
     ], 
     "ci_platforms": [
@@ -14623,28 +14771,6 @@
   }, 
   {
     "args": [
-      "metadata"
-    ], 
-    "ci_platforms": [
-      "windows", 
-      "linux", 
-      "mac", 
-      "posix"
-    ], 
-    "cpu_cost": 1.0, 
-    "exclude_configs": [], 
-    "flaky": false, 
-    "language": "c", 
-    "name": "h2_uchannel_test", 
-    "platforms": [
-      "windows", 
-      "linux", 
-      "mac", 
-      "posix"
-    ]
-  }, 
-  {
-    "args": [
       "negative_deadline"
     ], 
     "ci_platforms": [
@@ -14865,6 +14991,28 @@
   }, 
   {
     "args": [
+      "simple_metadata"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_uchannel_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "simple_request"
     ], 
     "ci_platforms": [
@@ -15089,7 +15237,7 @@
   }, 
   {
     "args": [
-      "channel_connectivity"
+      "compressed_payload"
     ], 
     "ci_platforms": [
       "linux", 
@@ -15109,27 +15257,7 @@
   }, 
   {
     "args": [
-      "channel_ping"
-    ], 
-    "ci_platforms": [
-      "linux", 
-      "mac", 
-      "posix"
-    ], 
-    "cpu_cost": 1.0, 
-    "exclude_configs": [], 
-    "flaky": false, 
-    "language": "c", 
-    "name": "h2_uds_test", 
-    "platforms": [
-      "linux", 
-      "mac", 
-      "posix"
-    ]
-  }, 
-  {
-    "args": [
-      "compressed_payload"
+      "connectivity"
     ], 
     "ci_platforms": [
       "linux", 
@@ -15329,26 +15457,6 @@
   }, 
   {
     "args": [
-      "metadata"
-    ], 
-    "ci_platforms": [
-      "linux", 
-      "mac", 
-      "posix"
-    ], 
-    "cpu_cost": 1.0, 
-    "exclude_configs": [], 
-    "flaky": false, 
-    "language": "c", 
-    "name": "h2_uds_test", 
-    "platforms": [
-      "linux", 
-      "mac", 
-      "posix"
-    ]
-  }, 
-  {
-    "args": [
       "negative_deadline"
     ], 
     "ci_platforms": [
@@ -15409,6 +15517,26 @@
   }, 
   {
     "args": [
+      "ping"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_uds_test", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "ping_pong_streaming"
     ], 
     "ci_platforms": [
@@ -15569,6 +15697,26 @@
   }, 
   {
     "args": [
+      "simple_metadata"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_uds_test", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "simple_request"
     ], 
     "ci_platforms": [
@@ -15753,7 +15901,7 @@
   }, 
   {
     "args": [
-      "channel_connectivity"
+      "compressed_payload"
     ], 
     "ci_platforms": [
       "linux"
@@ -15769,23 +15917,7 @@
   }, 
   {
     "args": [
-      "channel_ping"
-    ], 
-    "ci_platforms": [
-      "linux"
-    ], 
-    "cpu_cost": 1.0, 
-    "exclude_configs": [], 
-    "flaky": false, 
-    "language": "c", 
-    "name": "h2_uds+poll_test", 
-    "platforms": [
-      "linux"
-    ]
-  }, 
-  {
-    "args": [
-      "compressed_payload"
+      "connectivity"
     ], 
     "ci_platforms": [
       "linux"
@@ -15945,22 +16077,6 @@
   }, 
   {
     "args": [
-      "metadata"
-    ], 
-    "ci_platforms": [
-      "linux"
-    ], 
-    "cpu_cost": 1.0, 
-    "exclude_configs": [], 
-    "flaky": false, 
-    "language": "c", 
-    "name": "h2_uds+poll_test", 
-    "platforms": [
-      "linux"
-    ]
-  }, 
-  {
-    "args": [
       "negative_deadline"
     ], 
     "ci_platforms": [
@@ -16009,6 +16125,22 @@
   }, 
   {
     "args": [
+      "ping"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_uds+poll_test", 
+    "platforms": [
+      "linux"
+    ]
+  }, 
+  {
+    "args": [
       "ping_pong_streaming"
     ], 
     "ci_platforms": [
@@ -16137,6 +16269,22 @@
   }, 
   {
     "args": [
+      "simple_metadata"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_uds+poll_test", 
+    "platforms": [
+      "linux"
+    ]
+  }, 
+  {
+    "args": [
       "simple_request"
     ], 
     "ci_platforms": [
@@ -16345,7 +16493,7 @@
   }, 
   {
     "args": [
-      "channel_connectivity"
+      "compressed_payload"
     ], 
     "ci_platforms": [
       "windows", 
@@ -16367,29 +16515,7 @@
   }, 
   {
     "args": [
-      "channel_ping"
-    ], 
-    "ci_platforms": [
-      "windows", 
-      "linux", 
-      "mac", 
-      "posix"
-    ], 
-    "cpu_cost": 1.0, 
-    "exclude_configs": [], 
-    "flaky": false, 
-    "language": "c", 
-    "name": "h2_census_nosec_test", 
-    "platforms": [
-      "windows", 
-      "linux", 
-      "mac", 
-      "posix"
-    ]
-  }, 
-  {
-    "args": [
-      "compressed_payload"
+      "connectivity"
     ], 
     "ci_platforms": [
       "windows", 
@@ -16631,28 +16757,6 @@
   }, 
   {
     "args": [
-      "metadata"
-    ], 
-    "ci_platforms": [
-      "windows", 
-      "linux", 
-      "mac", 
-      "posix"
-    ], 
-    "cpu_cost": 1.0, 
-    "exclude_configs": [], 
-    "flaky": false, 
-    "language": "c", 
-    "name": "h2_census_nosec_test", 
-    "platforms": [
-      "windows", 
-      "linux", 
-      "mac", 
-      "posix"
-    ]
-  }, 
-  {
-    "args": [
       "negative_deadline"
     ], 
     "ci_platforms": [
@@ -16719,6 +16823,28 @@
   }, 
   {
     "args": [
+      "ping"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_census_nosec_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "ping_pong_streaming"
     ], 
     "ci_platforms": [
@@ -16895,6 +17021,28 @@
   }, 
   {
     "args": [
+      "simple_metadata"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_census_nosec_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "simple_request"
     ], 
     "ci_platforms": [
@@ -17115,7 +17263,7 @@
   }, 
   {
     "args": [
-      "channel_connectivity"
+      "compressed_payload"
     ], 
     "ci_platforms": [
       "windows", 
@@ -17137,29 +17285,7 @@
   }, 
   {
     "args": [
-      "channel_ping"
-    ], 
-    "ci_platforms": [
-      "windows", 
-      "linux", 
-      "mac", 
-      "posix"
-    ], 
-    "cpu_cost": 1.0, 
-    "exclude_configs": [], 
-    "flaky": false, 
-    "language": "c", 
-    "name": "h2_compress_nosec_test", 
-    "platforms": [
-      "windows", 
-      "linux", 
-      "mac", 
-      "posix"
-    ]
-  }, 
-  {
-    "args": [
-      "compressed_payload"
+      "connectivity"
     ], 
     "ci_platforms": [
       "windows", 
@@ -17401,28 +17527,6 @@
   }, 
   {
     "args": [
-      "metadata"
-    ], 
-    "ci_platforms": [
-      "windows", 
-      "linux", 
-      "mac", 
-      "posix"
-    ], 
-    "cpu_cost": 1.0, 
-    "exclude_configs": [], 
-    "flaky": false, 
-    "language": "c", 
-    "name": "h2_compress_nosec_test", 
-    "platforms": [
-      "windows", 
-      "linux", 
-      "mac", 
-      "posix"
-    ]
-  }, 
-  {
-    "args": [
       "negative_deadline"
     ], 
     "ci_platforms": [
@@ -17489,6 +17593,28 @@
   }, 
   {
     "args": [
+      "ping"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_compress_nosec_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "ping_pong_streaming"
     ], 
     "ci_platforms": [
@@ -17665,6 +17791,28 @@
   }, 
   {
     "args": [
+      "simple_metadata"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_compress_nosec_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "simple_request"
     ], 
     "ci_platforms": [
@@ -17885,7 +18033,7 @@
   }, 
   {
     "args": [
-      "channel_connectivity"
+      "compressed_payload"
     ], 
     "ci_platforms": [
       "windows", 
@@ -17907,29 +18055,7 @@
   }, 
   {
     "args": [
-      "channel_ping"
-    ], 
-    "ci_platforms": [
-      "windows", 
-      "linux", 
-      "mac", 
-      "posix"
-    ], 
-    "cpu_cost": 1.0, 
-    "exclude_configs": [], 
-    "flaky": false, 
-    "language": "c", 
-    "name": "h2_full_nosec_test", 
-    "platforms": [
-      "windows", 
-      "linux", 
-      "mac", 
-      "posix"
-    ]
-  }, 
-  {
-    "args": [
-      "compressed_payload"
+      "connectivity"
     ], 
     "ci_platforms": [
       "windows", 
@@ -18171,28 +18297,6 @@
   }, 
   {
     "args": [
-      "metadata"
-    ], 
-    "ci_platforms": [
-      "windows", 
-      "linux", 
-      "mac", 
-      "posix"
-    ], 
-    "cpu_cost": 1.0, 
-    "exclude_configs": [], 
-    "flaky": false, 
-    "language": "c", 
-    "name": "h2_full_nosec_test", 
-    "platforms": [
-      "windows", 
-      "linux", 
-      "mac", 
-      "posix"
-    ]
-  }, 
-  {
-    "args": [
       "negative_deadline"
     ], 
     "ci_platforms": [
@@ -18259,6 +18363,28 @@
   }, 
   {
     "args": [
+      "ping"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_full_nosec_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "ping_pong_streaming"
     ], 
     "ci_platforms": [
@@ -18435,6 +18561,28 @@
   }, 
   {
     "args": [
+      "simple_metadata"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_full_nosec_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "simple_request"
     ], 
     "ci_platforms": [
@@ -18607,7 +18755,7 @@
   }, 
   {
     "args": [
-      "channel_connectivity"
+      "compressed_payload"
     ], 
     "ci_platforms": [
       "linux"
@@ -18623,23 +18771,7 @@
   }, 
   {
     "args": [
-      "channel_ping"
-    ], 
-    "ci_platforms": [
-      "linux"
-    ], 
-    "cpu_cost": 1.0, 
-    "exclude_configs": [], 
-    "flaky": false, 
-    "language": "c", 
-    "name": "h2_full+pipe_nosec_test", 
-    "platforms": [
-      "linux"
-    ]
-  }, 
-  {
-    "args": [
-      "compressed_payload"
+      "connectivity"
     ], 
     "ci_platforms": [
       "linux"
@@ -18815,22 +18947,6 @@
   }, 
   {
     "args": [
-      "metadata"
-    ], 
-    "ci_platforms": [
-      "linux"
-    ], 
-    "cpu_cost": 1.0, 
-    "exclude_configs": [], 
-    "flaky": false, 
-    "language": "c", 
-    "name": "h2_full+pipe_nosec_test", 
-    "platforms": [
-      "linux"
-    ]
-  }, 
-  {
-    "args": [
       "negative_deadline"
     ], 
     "ci_platforms": [
@@ -18879,6 +18995,22 @@
   }, 
   {
     "args": [
+      "ping"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_full+pipe_nosec_test", 
+    "platforms": [
+      "linux"
+    ]
+  }, 
+  {
+    "args": [
       "ping_pong_streaming"
     ], 
     "ci_platforms": [
@@ -19007,6 +19139,22 @@
   }, 
   {
     "args": [
+      "simple_metadata"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_full+pipe_nosec_test", 
+    "platforms": [
+      "linux"
+    ]
+  }, 
+  {
+    "args": [
       "simple_request"
     ], 
     "ci_platforms": [
@@ -19167,7 +19315,7 @@
   }, 
   {
     "args": [
-      "channel_connectivity"
+      "compressed_payload"
     ], 
     "ci_platforms": [
       "linux"
@@ -19183,23 +19331,7 @@
   }, 
   {
     "args": [
-      "channel_ping"
-    ], 
-    "ci_platforms": [
-      "linux"
-    ], 
-    "cpu_cost": 1.0, 
-    "exclude_configs": [], 
-    "flaky": false, 
-    "language": "c", 
-    "name": "h2_full+poll_nosec_test", 
-    "platforms": [
-      "linux"
-    ]
-  }, 
-  {
-    "args": [
-      "compressed_payload"
+      "connectivity"
     ], 
     "ci_platforms": [
       "linux"
@@ -19375,22 +19507,6 @@
   }, 
   {
     "args": [
-      "metadata"
-    ], 
-    "ci_platforms": [
-      "linux"
-    ], 
-    "cpu_cost": 1.0, 
-    "exclude_configs": [], 
-    "flaky": false, 
-    "language": "c", 
-    "name": "h2_full+poll_nosec_test", 
-    "platforms": [
-      "linux"
-    ]
-  }, 
-  {
-    "args": [
       "negative_deadline"
     ], 
     "ci_platforms": [
@@ -19439,6 +19555,22 @@
   }, 
   {
     "args": [
+      "ping"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_full+poll_nosec_test", 
+    "platforms": [
+      "linux"
+    ]
+  }, 
+  {
+    "args": [
       "ping_pong_streaming"
     ], 
     "ci_platforms": [
@@ -19567,6 +19699,22 @@
   }, 
   {
     "args": [
+      "simple_metadata"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_full+poll_nosec_test", 
+    "platforms": [
+      "linux"
+    ]
+  }, 
+  {
+    "args": [
       "simple_request"
     ], 
     "ci_platforms": [
@@ -19727,7 +19875,7 @@
   }, 
   {
     "args": [
-      "channel_connectivity"
+      "compressed_payload"
     ], 
     "ci_platforms": [
       "linux"
@@ -19743,23 +19891,7 @@
   }, 
   {
     "args": [
-      "channel_ping"
-    ], 
-    "ci_platforms": [
-      "linux"
-    ], 
-    "cpu_cost": 1.0, 
-    "exclude_configs": [], 
-    "flaky": false, 
-    "language": "c", 
-    "name": "h2_full+poll+pipe_nosec_test", 
-    "platforms": [
-      "linux"
-    ]
-  }, 
-  {
-    "args": [
-      "compressed_payload"
+      "connectivity"
     ], 
     "ci_platforms": [
       "linux"
@@ -19935,22 +20067,6 @@
   }, 
   {
     "args": [
-      "metadata"
-    ], 
-    "ci_platforms": [
-      "linux"
-    ], 
-    "cpu_cost": 1.0, 
-    "exclude_configs": [], 
-    "flaky": false, 
-    "language": "c", 
-    "name": "h2_full+poll+pipe_nosec_test", 
-    "platforms": [
-      "linux"
-    ]
-  }, 
-  {
-    "args": [
       "negative_deadline"
     ], 
     "ci_platforms": [
@@ -19999,6 +20115,22 @@
   }, 
   {
     "args": [
+      "ping"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_full+poll+pipe_nosec_test", 
+    "platforms": [
+      "linux"
+    ]
+  }, 
+  {
+    "args": [
       "ping_pong_streaming"
     ], 
     "ci_platforms": [
@@ -20127,6 +20259,22 @@
   }, 
   {
     "args": [
+      "simple_metadata"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_full+poll+pipe_nosec_test", 
+    "platforms": [
+      "linux"
+    ]
+  }, 
+  {
+    "args": [
       "simple_request"
     ], 
     "ci_platforms": [
@@ -20495,27 +20643,6 @@
   }, 
   {
     "args": [
-      "metadata"
-    ], 
-    "ci_platforms": [
-      "windows", 
-      "linux", 
-      "posix"
-    ], 
-    "cpu_cost": 1.0, 
-    "exclude_configs": [], 
-    "flaky": false, 
-    "language": "c", 
-    "name": "h2_proxy_nosec_test", 
-    "platforms": [
-      "windows", 
-      "linux", 
-      "mac", 
-      "posix"
-    ]
-  }, 
-  {
-    "args": [
       "negative_deadline"
     ], 
     "ci_platforms": [
@@ -20726,6 +20853,27 @@
   }, 
   {
     "args": [
+      "simple_metadata"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_proxy_nosec_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "simple_request"
     ], 
     "ci_platforms": [
@@ -21125,27 +21273,6 @@
   }, 
   {
     "args": [
-      "metadata"
-    ], 
-    "ci_platforms": [
-      "windows", 
-      "linux", 
-      "posix"
-    ], 
-    "cpu_cost": 1.0, 
-    "exclude_configs": [], 
-    "flaky": false, 
-    "language": "c", 
-    "name": "h2_sockpair_nosec_test", 
-    "platforms": [
-      "windows", 
-      "linux", 
-      "mac", 
-      "posix"
-    ]
-  }, 
-  {
-    "args": [
       "negative_deadline"
     ], 
     "ci_platforms": [
@@ -21356,6 +21483,27 @@
   }, 
   {
     "args": [
+      "simple_metadata"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_sockpair_nosec_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "simple_request"
     ], 
     "ci_platforms": [
@@ -21750,28 +21898,6 @@
   }, 
   {
     "args": [
-      "metadata"
-    ], 
-    "ci_platforms": [
-      "windows", 
-      "linux", 
-      "mac", 
-      "posix"
-    ], 
-    "cpu_cost": 1.0, 
-    "exclude_configs": [], 
-    "flaky": false, 
-    "language": "c", 
-    "name": "h2_sockpair+trace_nosec_test", 
-    "platforms": [
-      "windows", 
-      "linux", 
-      "mac", 
-      "posix"
-    ]
-  }, 
-  {
-    "args": [
       "negative_deadline"
     ], 
     "ci_platforms": [
@@ -21992,6 +22118,28 @@
   }, 
   {
     "args": [
+      "simple_metadata"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_sockpair+trace_nosec_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "simple_request"
     ], 
     "ci_platforms": [
@@ -22393,27 +22541,6 @@
   }, 
   {
     "args": [
-      "metadata"
-    ], 
-    "ci_platforms": [
-      "windows", 
-      "linux", 
-      "posix"
-    ], 
-    "cpu_cost": 1.0, 
-    "exclude_configs": [], 
-    "flaky": false, 
-    "language": "c", 
-    "name": "h2_sockpair_1byte_nosec_test", 
-    "platforms": [
-      "windows", 
-      "linux", 
-      "mac", 
-      "posix"
-    ]
-  }, 
-  {
-    "args": [
       "negative_deadline"
     ], 
     "ci_platforms": [
@@ -22624,6 +22751,27 @@
   }, 
   {
     "args": [
+      "simple_metadata"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_sockpair_1byte_nosec_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "simple_request"
     ], 
     "ci_platforms": [
@@ -23040,28 +23188,6 @@
   }, 
   {
     "args": [
-      "metadata"
-    ], 
-    "ci_platforms": [
-      "windows", 
-      "linux", 
-      "mac", 
-      "posix"
-    ], 
-    "cpu_cost": 1.0, 
-    "exclude_configs": [], 
-    "flaky": false, 
-    "language": "c", 
-    "name": "h2_uchannel_nosec_test", 
-    "platforms": [
-      "windows", 
-      "linux", 
-      "mac", 
-      "posix"
-    ]
-  }, 
-  {
-    "args": [
       "negative_deadline"
     ], 
     "ci_platforms": [
@@ -23282,6 +23408,28 @@
   }, 
   {
     "args": [
+      "simple_metadata"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_uchannel_nosec_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "simple_request"
     ], 
     "ci_platforms": [
@@ -23486,7 +23634,7 @@
   }, 
   {
     "args": [
-      "channel_connectivity"
+      "compressed_payload"
     ], 
     "ci_platforms": [
       "linux", 
@@ -23506,27 +23654,7 @@
   }, 
   {
     "args": [
-      "channel_ping"
-    ], 
-    "ci_platforms": [
-      "linux", 
-      "mac", 
-      "posix"
-    ], 
-    "cpu_cost": 1.0, 
-    "exclude_configs": [], 
-    "flaky": false, 
-    "language": "c", 
-    "name": "h2_uds_nosec_test", 
-    "platforms": [
-      "linux", 
-      "mac", 
-      "posix"
-    ]
-  }, 
-  {
-    "args": [
-      "compressed_payload"
+      "connectivity"
     ], 
     "ci_platforms": [
       "linux", 
@@ -23726,26 +23854,6 @@
   }, 
   {
     "args": [
-      "metadata"
-    ], 
-    "ci_platforms": [
-      "linux", 
-      "mac", 
-      "posix"
-    ], 
-    "cpu_cost": 1.0, 
-    "exclude_configs": [], 
-    "flaky": false, 
-    "language": "c", 
-    "name": "h2_uds_nosec_test", 
-    "platforms": [
-      "linux", 
-      "mac", 
-      "posix"
-    ]
-  }, 
-  {
-    "args": [
       "negative_deadline"
     ], 
     "ci_platforms": [
@@ -23806,6 +23914,26 @@
   }, 
   {
     "args": [
+      "ping"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_uds_nosec_test", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "ping_pong_streaming"
     ], 
     "ci_platforms": [
@@ -23966,6 +24094,26 @@
   }, 
   {
     "args": [
+      "simple_metadata"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_uds_nosec_test", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "simple_request"
     ], 
     "ci_platforms": [
@@ -24134,7 +24282,7 @@
   }, 
   {
     "args": [
-      "channel_connectivity"
+      "compressed_payload"
     ], 
     "ci_platforms": [
       "linux"
@@ -24150,23 +24298,7 @@
   }, 
   {
     "args": [
-      "channel_ping"
-    ], 
-    "ci_platforms": [
-      "linux"
-    ], 
-    "cpu_cost": 1.0, 
-    "exclude_configs": [], 
-    "flaky": false, 
-    "language": "c", 
-    "name": "h2_uds+poll_nosec_test", 
-    "platforms": [
-      "linux"
-    ]
-  }, 
-  {
-    "args": [
-      "compressed_payload"
+      "connectivity"
     ], 
     "ci_platforms": [
       "linux"
@@ -24326,22 +24458,6 @@
   }, 
   {
     "args": [
-      "metadata"
-    ], 
-    "ci_platforms": [
-      "linux"
-    ], 
-    "cpu_cost": 1.0, 
-    "exclude_configs": [], 
-    "flaky": false, 
-    "language": "c", 
-    "name": "h2_uds+poll_nosec_test", 
-    "platforms": [
-      "linux"
-    ]
-  }, 
-  {
-    "args": [
       "negative_deadline"
     ], 
     "ci_platforms": [
@@ -24390,6 +24506,22 @@
   }, 
   {
     "args": [
+      "ping"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_uds+poll_nosec_test", 
+    "platforms": [
+      "linux"
+    ]
+  }, 
+  {
+    "args": [
       "ping_pong_streaming"
     ], 
     "ci_platforms": [
@@ -24518,6 +24650,22 @@
   }, 
   {
     "args": [
+      "simple_metadata"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_uds+poll_nosec_test", 
+    "platforms": [
+      "linux"
+    ]
+  }, 
+  {
+    "args": [
       "simple_request"
     ], 
     "ci_platforms": [
diff --git a/vsprojects/buildtests_c.sln b/vsprojects/buildtests_c.sln
index b846bd1..a13b6dd 100644
--- a/vsprojects/buildtests_c.sln
+++ b/vsprojects/buildtests_c.sln
@@ -30,6 +30,15 @@
         	lib = "True"
 	EndProjectSection
 EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "grpc_dll", "vcxproj\.\grpc_dll\grpc_dll.vcxproj", "{A2F6CBBA-A553-41B3-A7DE-F26DECCC27F0}"
+	ProjectSection(myProperties) = preProject
+        	lib = "True"
+	EndProjectSection
+	ProjectSection(ProjectDependencies) = postProject
+		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
+		{29D16885-7228-4C31-81ED-5F9187C7F2A9} = {29D16885-7228-4C31-81ED-5F9187C7F2A9}
+	EndProjectSection
+EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "grpc_test_util", "vcxproj\.\grpc_test_util\grpc_test_util.vcxproj", "{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}"
 	ProjectSection(myProperties) = preProject
         	lib = "True"
@@ -183,17 +192,6 @@
 		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
 	EndProjectSection
 EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "census_log_test", "vcxproj\test\census_log_test\census_log_test.vcxproj", "{C27CEE16-2BEC-5572-3956-677E9F6F8BED}"
-	ProjectSection(myProperties) = preProject
-        	lib = "False"
-	EndProjectSection
-	ProjectSection(ProjectDependencies) = postProject
-		{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B} = {17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}
-		{29D16885-7228-4C31-81ED-5F9187C7F2A9} = {29D16885-7228-4C31-81ED-5F9187C7F2A9}
-		{EAB0A629-17A9-44DB-B5FF-E91A721FE037} = {EAB0A629-17A9-44DB-B5FF-E91A721FE037}
-		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
-	EndProjectSection
-EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "channel_create_test", "vcxproj\test\channel_create_test\channel_create_test.vcxproj", "{AFC88484-3A2E-32BC-25B2-23DF741D4F3D}"
 	ProjectSection(myProperties) = preProject
         	lib = "False"
@@ -354,15 +352,6 @@
 		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
 	EndProjectSection
 EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gpr_file_test", "vcxproj\test\gpr_file_test\gpr_file_test.vcxproj", "{13B0BA63-A3A4-D0E7-1DF2-C73281EB0678}"
-	ProjectSection(myProperties) = preProject
-        	lib = "False"
-	EndProjectSection
-	ProjectSection(ProjectDependencies) = postProject
-		{EAB0A629-17A9-44DB-B5FF-E91A721FE037} = {EAB0A629-17A9-44DB-B5FF-E91A721FE037}
-		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
-	EndProjectSection
-EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gpr_histogram_test", "vcxproj\test\gpr_histogram_test\gpr_histogram_test.vcxproj", "{EEBDE4C3-0130-5BD1-E85F-527B3E68FE11}"
 	ProjectSection(myProperties) = preProject
         	lib = "False"
@@ -381,6 +370,15 @@
 		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
 	EndProjectSection
 EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gpr_load_file_test", "vcxproj\test\gpr_load_file_test\gpr_load_file_test.vcxproj", "{B36DE5B4-8B73-1194-7539-974D9524D609}"
+	ProjectSection(myProperties) = preProject
+        	lib = "False"
+	EndProjectSection
+	ProjectSection(ProjectDependencies) = postProject
+		{EAB0A629-17A9-44DB-B5FF-E91A721FE037} = {EAB0A629-17A9-44DB-B5FF-E91A721FE037}
+		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
+	EndProjectSection
+EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gpr_log_test", "vcxproj\test\gpr_log_test\gpr_log_test.vcxproj", "{38797EE3-62CC-3CBF-18D5-009ED6DD0BEC}"
 	ProjectSection(myProperties) = preProject
         	lib = "False"
@@ -482,7 +480,7 @@
 		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
 	EndProjectSection
 EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "grpc_base64_test", "vcxproj\test\grpc_base64_test\grpc_base64_test.vcxproj", "{759A2BB1-DA1B-196C-94A3-98687BBC9F36}"
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "grpc_b64_test", "vcxproj\test\grpc_b64_test\grpc_b64_test.vcxproj", "{A19FD81D-DF19-B8A4-4A8A-6967217FEC85}"
 	ProjectSection(myProperties) = preProject
         	lib = "False"
 	EndProjectSection
@@ -766,6 +764,17 @@
 		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
 	EndProjectSection
 EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mlog_test", "vcxproj\test\mlog_test\mlog_test.vcxproj", "{9345E329-80F3-DED4-FDC3-BF63FCEA2C03}"
+	ProjectSection(myProperties) = preProject
+        	lib = "False"
+	EndProjectSection
+	ProjectSection(ProjectDependencies) = postProject
+		{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B} = {17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}
+		{29D16885-7228-4C31-81ED-5F9187C7F2A9} = {29D16885-7228-4C31-81ED-5F9187C7F2A9}
+		{EAB0A629-17A9-44DB-B5FF-E91A721FE037} = {EAB0A629-17A9-44DB-B5FF-E91A721FE037}
+		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
+	EndProjectSection
+EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "multiple_server_queues_test", "vcxproj\test\multiple_server_queues_test\multiple_server_queues_test.vcxproj", "{88AF688E-E43C-5E20-6966-CF559F597D82}"
 	ProjectSection(myProperties) = preProject
         	lib = "False"
@@ -1398,6 +1407,22 @@
 		{A828FD72-44CE-4EA5-8966-6E4624458D58}.Release-DLL|Win32.Build.0 = Release|Win32
 		{A828FD72-44CE-4EA5-8966-6E4624458D58}.Release-DLL|x64.ActiveCfg = Release|x64
 		{A828FD72-44CE-4EA5-8966-6E4624458D58}.Release-DLL|x64.Build.0 = Release|x64
+		{A2F6CBBA-A553-41B3-A7DE-F26DECCC27F0}.Debug|Win32.ActiveCfg = Debug|Win32
+		{A2F6CBBA-A553-41B3-A7DE-F26DECCC27F0}.Debug|x64.ActiveCfg = Debug|x64
+		{A2F6CBBA-A553-41B3-A7DE-F26DECCC27F0}.Release|Win32.ActiveCfg = Release|Win32
+		{A2F6CBBA-A553-41B3-A7DE-F26DECCC27F0}.Release|x64.ActiveCfg = Release|x64
+		{A2F6CBBA-A553-41B3-A7DE-F26DECCC27F0}.Debug|Win32.Build.0 = Debug|Win32
+		{A2F6CBBA-A553-41B3-A7DE-F26DECCC27F0}.Debug|x64.Build.0 = Debug|x64
+		{A2F6CBBA-A553-41B3-A7DE-F26DECCC27F0}.Release|Win32.Build.0 = Release|Win32
+		{A2F6CBBA-A553-41B3-A7DE-F26DECCC27F0}.Release|x64.Build.0 = Release|x64
+		{A2F6CBBA-A553-41B3-A7DE-F26DECCC27F0}.Debug-DLL|Win32.ActiveCfg = Debug|Win32
+		{A2F6CBBA-A553-41B3-A7DE-F26DECCC27F0}.Debug-DLL|Win32.Build.0 = Debug|Win32
+		{A2F6CBBA-A553-41B3-A7DE-F26DECCC27F0}.Debug-DLL|x64.ActiveCfg = Debug|x64
+		{A2F6CBBA-A553-41B3-A7DE-F26DECCC27F0}.Debug-DLL|x64.Build.0 = Debug|x64
+		{A2F6CBBA-A553-41B3-A7DE-F26DECCC27F0}.Release-DLL|Win32.ActiveCfg = Release|Win32
+		{A2F6CBBA-A553-41B3-A7DE-F26DECCC27F0}.Release-DLL|Win32.Build.0 = Release|Win32
+		{A2F6CBBA-A553-41B3-A7DE-F26DECCC27F0}.Release-DLL|x64.ActiveCfg = Release|x64
+		{A2F6CBBA-A553-41B3-A7DE-F26DECCC27F0}.Release-DLL|x64.Build.0 = Release|x64
 		{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}.Debug|Win32.ActiveCfg = Debug|Win32
 		{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}.Debug|x64.ActiveCfg = Debug|x64
 		{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}.Release|Win32.ActiveCfg = Release|Win32
@@ -1638,22 +1663,6 @@
 		{5C1CFC2D-AF3C-D7CB-BA74-D267E91CBC73}.Release-DLL|Win32.Build.0 = Release|Win32
 		{5C1CFC2D-AF3C-D7CB-BA74-D267E91CBC73}.Release-DLL|x64.ActiveCfg = Release|x64
 		{5C1CFC2D-AF3C-D7CB-BA74-D267E91CBC73}.Release-DLL|x64.Build.0 = Release|x64
-		{C27CEE16-2BEC-5572-3956-677E9F6F8BED}.Debug|Win32.ActiveCfg = Debug|Win32
-		{C27CEE16-2BEC-5572-3956-677E9F6F8BED}.Debug|x64.ActiveCfg = Debug|x64
-		{C27CEE16-2BEC-5572-3956-677E9F6F8BED}.Release|Win32.ActiveCfg = Release|Win32
-		{C27CEE16-2BEC-5572-3956-677E9F6F8BED}.Release|x64.ActiveCfg = Release|x64
-		{C27CEE16-2BEC-5572-3956-677E9F6F8BED}.Debug|Win32.Build.0 = Debug|Win32
-		{C27CEE16-2BEC-5572-3956-677E9F6F8BED}.Debug|x64.Build.0 = Debug|x64
-		{C27CEE16-2BEC-5572-3956-677E9F6F8BED}.Release|Win32.Build.0 = Release|Win32
-		{C27CEE16-2BEC-5572-3956-677E9F6F8BED}.Release|x64.Build.0 = Release|x64
-		{C27CEE16-2BEC-5572-3956-677E9F6F8BED}.Debug-DLL|Win32.ActiveCfg = Debug|Win32
-		{C27CEE16-2BEC-5572-3956-677E9F6F8BED}.Debug-DLL|Win32.Build.0 = Debug|Win32
-		{C27CEE16-2BEC-5572-3956-677E9F6F8BED}.Debug-DLL|x64.ActiveCfg = Debug|x64
-		{C27CEE16-2BEC-5572-3956-677E9F6F8BED}.Debug-DLL|x64.Build.0 = Debug|x64
-		{C27CEE16-2BEC-5572-3956-677E9F6F8BED}.Release-DLL|Win32.ActiveCfg = Release|Win32
-		{C27CEE16-2BEC-5572-3956-677E9F6F8BED}.Release-DLL|Win32.Build.0 = Release|Win32
-		{C27CEE16-2BEC-5572-3956-677E9F6F8BED}.Release-DLL|x64.ActiveCfg = Release|x64
-		{C27CEE16-2BEC-5572-3956-677E9F6F8BED}.Release-DLL|x64.Build.0 = Release|x64
 		{AFC88484-3A2E-32BC-25B2-23DF741D4F3D}.Debug|Win32.ActiveCfg = Debug|Win32
 		{AFC88484-3A2E-32BC-25B2-23DF741D4F3D}.Debug|x64.ActiveCfg = Debug|x64
 		{AFC88484-3A2E-32BC-25B2-23DF741D4F3D}.Release|Win32.ActiveCfg = Release|Win32
@@ -1910,22 +1919,6 @@
 		{07149650-E8AF-B3D8-9D5B-BC34DC909DB8}.Release-DLL|Win32.Build.0 = Release|Win32
 		{07149650-E8AF-B3D8-9D5B-BC34DC909DB8}.Release-DLL|x64.ActiveCfg = Release|x64
 		{07149650-E8AF-B3D8-9D5B-BC34DC909DB8}.Release-DLL|x64.Build.0 = Release|x64
-		{13B0BA63-A3A4-D0E7-1DF2-C73281EB0678}.Debug|Win32.ActiveCfg = Debug|Win32
-		{13B0BA63-A3A4-D0E7-1DF2-C73281EB0678}.Debug|x64.ActiveCfg = Debug|x64
-		{13B0BA63-A3A4-D0E7-1DF2-C73281EB0678}.Release|Win32.ActiveCfg = Release|Win32
-		{13B0BA63-A3A4-D0E7-1DF2-C73281EB0678}.Release|x64.ActiveCfg = Release|x64
-		{13B0BA63-A3A4-D0E7-1DF2-C73281EB0678}.Debug|Win32.Build.0 = Debug|Win32
-		{13B0BA63-A3A4-D0E7-1DF2-C73281EB0678}.Debug|x64.Build.0 = Debug|x64
-		{13B0BA63-A3A4-D0E7-1DF2-C73281EB0678}.Release|Win32.Build.0 = Release|Win32
-		{13B0BA63-A3A4-D0E7-1DF2-C73281EB0678}.Release|x64.Build.0 = Release|x64
-		{13B0BA63-A3A4-D0E7-1DF2-C73281EB0678}.Debug-DLL|Win32.ActiveCfg = Debug|Win32
-		{13B0BA63-A3A4-D0E7-1DF2-C73281EB0678}.Debug-DLL|Win32.Build.0 = Debug|Win32
-		{13B0BA63-A3A4-D0E7-1DF2-C73281EB0678}.Debug-DLL|x64.ActiveCfg = Debug|x64
-		{13B0BA63-A3A4-D0E7-1DF2-C73281EB0678}.Debug-DLL|x64.Build.0 = Debug|x64
-		{13B0BA63-A3A4-D0E7-1DF2-C73281EB0678}.Release-DLL|Win32.ActiveCfg = Release|Win32
-		{13B0BA63-A3A4-D0E7-1DF2-C73281EB0678}.Release-DLL|Win32.Build.0 = Release|Win32
-		{13B0BA63-A3A4-D0E7-1DF2-C73281EB0678}.Release-DLL|x64.ActiveCfg = Release|x64
-		{13B0BA63-A3A4-D0E7-1DF2-C73281EB0678}.Release-DLL|x64.Build.0 = Release|x64
 		{EEBDE4C3-0130-5BD1-E85F-527B3E68FE11}.Debug|Win32.ActiveCfg = Debug|Win32
 		{EEBDE4C3-0130-5BD1-E85F-527B3E68FE11}.Debug|x64.ActiveCfg = Debug|x64
 		{EEBDE4C3-0130-5BD1-E85F-527B3E68FE11}.Release|Win32.ActiveCfg = Release|Win32
@@ -1958,6 +1951,22 @@
 		{64728265-92F9-103E-6720-8935385458DF}.Release-DLL|Win32.Build.0 = Release|Win32
 		{64728265-92F9-103E-6720-8935385458DF}.Release-DLL|x64.ActiveCfg = Release|x64
 		{64728265-92F9-103E-6720-8935385458DF}.Release-DLL|x64.Build.0 = Release|x64
+		{B36DE5B4-8B73-1194-7539-974D9524D609}.Debug|Win32.ActiveCfg = Debug|Win32
+		{B36DE5B4-8B73-1194-7539-974D9524D609}.Debug|x64.ActiveCfg = Debug|x64
+		{B36DE5B4-8B73-1194-7539-974D9524D609}.Release|Win32.ActiveCfg = Release|Win32
+		{B36DE5B4-8B73-1194-7539-974D9524D609}.Release|x64.ActiveCfg = Release|x64
+		{B36DE5B4-8B73-1194-7539-974D9524D609}.Debug|Win32.Build.0 = Debug|Win32
+		{B36DE5B4-8B73-1194-7539-974D9524D609}.Debug|x64.Build.0 = Debug|x64
+		{B36DE5B4-8B73-1194-7539-974D9524D609}.Release|Win32.Build.0 = Release|Win32
+		{B36DE5B4-8B73-1194-7539-974D9524D609}.Release|x64.Build.0 = Release|x64
+		{B36DE5B4-8B73-1194-7539-974D9524D609}.Debug-DLL|Win32.ActiveCfg = Debug|Win32
+		{B36DE5B4-8B73-1194-7539-974D9524D609}.Debug-DLL|Win32.Build.0 = Debug|Win32
+		{B36DE5B4-8B73-1194-7539-974D9524D609}.Debug-DLL|x64.ActiveCfg = Debug|x64
+		{B36DE5B4-8B73-1194-7539-974D9524D609}.Debug-DLL|x64.Build.0 = Debug|x64
+		{B36DE5B4-8B73-1194-7539-974D9524D609}.Release-DLL|Win32.ActiveCfg = Release|Win32
+		{B36DE5B4-8B73-1194-7539-974D9524D609}.Release-DLL|Win32.Build.0 = Release|Win32
+		{B36DE5B4-8B73-1194-7539-974D9524D609}.Release-DLL|x64.ActiveCfg = Release|x64
+		{B36DE5B4-8B73-1194-7539-974D9524D609}.Release-DLL|x64.Build.0 = Release|x64
 		{38797EE3-62CC-3CBF-18D5-009ED6DD0BEC}.Debug|Win32.ActiveCfg = Debug|Win32
 		{38797EE3-62CC-3CBF-18D5-009ED6DD0BEC}.Debug|x64.ActiveCfg = Debug|x64
 		{38797EE3-62CC-3CBF-18D5-009ED6DD0BEC}.Release|Win32.ActiveCfg = Release|Win32
@@ -2134,22 +2143,22 @@
 		{C65A4336-92D6-D6A0-EB86-E3AA425222D0}.Release-DLL|Win32.Build.0 = Release|Win32
 		{C65A4336-92D6-D6A0-EB86-E3AA425222D0}.Release-DLL|x64.ActiveCfg = Release|x64
 		{C65A4336-92D6-D6A0-EB86-E3AA425222D0}.Release-DLL|x64.Build.0 = Release|x64
-		{759A2BB1-DA1B-196C-94A3-98687BBC9F36}.Debug|Win32.ActiveCfg = Debug|Win32
-		{759A2BB1-DA1B-196C-94A3-98687BBC9F36}.Debug|x64.ActiveCfg = Debug|x64
-		{759A2BB1-DA1B-196C-94A3-98687BBC9F36}.Release|Win32.ActiveCfg = Release|Win32
-		{759A2BB1-DA1B-196C-94A3-98687BBC9F36}.Release|x64.ActiveCfg = Release|x64
-		{759A2BB1-DA1B-196C-94A3-98687BBC9F36}.Debug|Win32.Build.0 = Debug|Win32
-		{759A2BB1-DA1B-196C-94A3-98687BBC9F36}.Debug|x64.Build.0 = Debug|x64
-		{759A2BB1-DA1B-196C-94A3-98687BBC9F36}.Release|Win32.Build.0 = Release|Win32
-		{759A2BB1-DA1B-196C-94A3-98687BBC9F36}.Release|x64.Build.0 = Release|x64
-		{759A2BB1-DA1B-196C-94A3-98687BBC9F36}.Debug-DLL|Win32.ActiveCfg = Debug|Win32
-		{759A2BB1-DA1B-196C-94A3-98687BBC9F36}.Debug-DLL|Win32.Build.0 = Debug|Win32
-		{759A2BB1-DA1B-196C-94A3-98687BBC9F36}.Debug-DLL|x64.ActiveCfg = Debug|x64
-		{759A2BB1-DA1B-196C-94A3-98687BBC9F36}.Debug-DLL|x64.Build.0 = Debug|x64
-		{759A2BB1-DA1B-196C-94A3-98687BBC9F36}.Release-DLL|Win32.ActiveCfg = Release|Win32
-		{759A2BB1-DA1B-196C-94A3-98687BBC9F36}.Release-DLL|Win32.Build.0 = Release|Win32
-		{759A2BB1-DA1B-196C-94A3-98687BBC9F36}.Release-DLL|x64.ActiveCfg = Release|x64
-		{759A2BB1-DA1B-196C-94A3-98687BBC9F36}.Release-DLL|x64.Build.0 = Release|x64
+		{A19FD81D-DF19-B8A4-4A8A-6967217FEC85}.Debug|Win32.ActiveCfg = Debug|Win32
+		{A19FD81D-DF19-B8A4-4A8A-6967217FEC85}.Debug|x64.ActiveCfg = Debug|x64
+		{A19FD81D-DF19-B8A4-4A8A-6967217FEC85}.Release|Win32.ActiveCfg = Release|Win32
+		{A19FD81D-DF19-B8A4-4A8A-6967217FEC85}.Release|x64.ActiveCfg = Release|x64
+		{A19FD81D-DF19-B8A4-4A8A-6967217FEC85}.Debug|Win32.Build.0 = Debug|Win32
+		{A19FD81D-DF19-B8A4-4A8A-6967217FEC85}.Debug|x64.Build.0 = Debug|x64
+		{A19FD81D-DF19-B8A4-4A8A-6967217FEC85}.Release|Win32.Build.0 = Release|Win32
+		{A19FD81D-DF19-B8A4-4A8A-6967217FEC85}.Release|x64.Build.0 = Release|x64
+		{A19FD81D-DF19-B8A4-4A8A-6967217FEC85}.Debug-DLL|Win32.ActiveCfg = Debug|Win32
+		{A19FD81D-DF19-B8A4-4A8A-6967217FEC85}.Debug-DLL|Win32.Build.0 = Debug|Win32
+		{A19FD81D-DF19-B8A4-4A8A-6967217FEC85}.Debug-DLL|x64.ActiveCfg = Debug|x64
+		{A19FD81D-DF19-B8A4-4A8A-6967217FEC85}.Debug-DLL|x64.Build.0 = Debug|x64
+		{A19FD81D-DF19-B8A4-4A8A-6967217FEC85}.Release-DLL|Win32.ActiveCfg = Release|Win32
+		{A19FD81D-DF19-B8A4-4A8A-6967217FEC85}.Release-DLL|Win32.Build.0 = Release|Win32
+		{A19FD81D-DF19-B8A4-4A8A-6967217FEC85}.Release-DLL|x64.ActiveCfg = Release|x64
+		{A19FD81D-DF19-B8A4-4A8A-6967217FEC85}.Release-DLL|x64.Build.0 = Release|x64
 		{82124768-C986-6C10-8BCC-B255B7C84722}.Debug|Win32.ActiveCfg = Debug|Win32
 		{82124768-C986-6C10-8BCC-B255B7C84722}.Debug|x64.ActiveCfg = Debug|x64
 		{82124768-C986-6C10-8BCC-B255B7C84722}.Release|Win32.ActiveCfg = Release|Win32
@@ -2550,6 +2559,22 @@
 		{07170557-CCB0-D23C-8018-C2909D115DF9}.Release-DLL|Win32.Build.0 = Release|Win32
 		{07170557-CCB0-D23C-8018-C2909D115DF9}.Release-DLL|x64.ActiveCfg = Release|x64
 		{07170557-CCB0-D23C-8018-C2909D115DF9}.Release-DLL|x64.Build.0 = Release|x64
+		{9345E329-80F3-DED4-FDC3-BF63FCEA2C03}.Debug|Win32.ActiveCfg = Debug|Win32
+		{9345E329-80F3-DED4-FDC3-BF63FCEA2C03}.Debug|x64.ActiveCfg = Debug|x64
+		{9345E329-80F3-DED4-FDC3-BF63FCEA2C03}.Release|Win32.ActiveCfg = Release|Win32
+		{9345E329-80F3-DED4-FDC3-BF63FCEA2C03}.Release|x64.ActiveCfg = Release|x64
+		{9345E329-80F3-DED4-FDC3-BF63FCEA2C03}.Debug|Win32.Build.0 = Debug|Win32
+		{9345E329-80F3-DED4-FDC3-BF63FCEA2C03}.Debug|x64.Build.0 = Debug|x64
+		{9345E329-80F3-DED4-FDC3-BF63FCEA2C03}.Release|Win32.Build.0 = Release|Win32
+		{9345E329-80F3-DED4-FDC3-BF63FCEA2C03}.Release|x64.Build.0 = Release|x64
+		{9345E329-80F3-DED4-FDC3-BF63FCEA2C03}.Debug-DLL|Win32.ActiveCfg = Debug|Win32
+		{9345E329-80F3-DED4-FDC3-BF63FCEA2C03}.Debug-DLL|Win32.Build.0 = Debug|Win32
+		{9345E329-80F3-DED4-FDC3-BF63FCEA2C03}.Debug-DLL|x64.ActiveCfg = Debug|x64
+		{9345E329-80F3-DED4-FDC3-BF63FCEA2C03}.Debug-DLL|x64.Build.0 = Debug|x64
+		{9345E329-80F3-DED4-FDC3-BF63FCEA2C03}.Release-DLL|Win32.ActiveCfg = Release|Win32
+		{9345E329-80F3-DED4-FDC3-BF63FCEA2C03}.Release-DLL|Win32.Build.0 = Release|Win32
+		{9345E329-80F3-DED4-FDC3-BF63FCEA2C03}.Release-DLL|x64.ActiveCfg = Release|x64
+		{9345E329-80F3-DED4-FDC3-BF63FCEA2C03}.Release-DLL|x64.Build.0 = Release|x64
 		{88AF688E-E43C-5E20-6966-CF559F597D82}.Debug|Win32.ActiveCfg = Debug|Win32
 		{88AF688E-E43C-5E20-6966-CF559F597D82}.Debug|x64.ActiveCfg = Debug|x64
 		{88AF688E-E43C-5E20-6966-CF559F597D82}.Release|Win32.ActiveCfg = Release|Win32
diff --git a/vsprojects/grpc.sln b/vsprojects/grpc.sln
index 53c04fe..ffcc682 100644
--- a/vsprojects/grpc.sln
+++ b/vsprojects/grpc.sln
@@ -30,6 +30,15 @@
         	lib = "True"
 	EndProjectSection
 EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "grpc_dll", "vcxproj\.\grpc_dll\grpc_dll.vcxproj", "{A2F6CBBA-A553-41B3-A7DE-F26DECCC27F0}"
+	ProjectSection(myProperties) = preProject
+        	lib = "True"
+	EndProjectSection
+	ProjectSection(ProjectDependencies) = postProject
+		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
+		{29D16885-7228-4C31-81ED-5F9187C7F2A9} = {29D16885-7228-4C31-81ED-5F9187C7F2A9}
+	EndProjectSection
+EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "grpc_test_util", "vcxproj\.\grpc_test_util\grpc_test_util.vcxproj", "{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}"
 	ProjectSection(myProperties) = preProject
         	lib = "True"
@@ -245,6 +254,22 @@
 		{A828FD72-44CE-4EA5-8966-6E4624458D58}.Release-DLL|Win32.Build.0 = Release|Win32
 		{A828FD72-44CE-4EA5-8966-6E4624458D58}.Release-DLL|x64.ActiveCfg = Release|x64
 		{A828FD72-44CE-4EA5-8966-6E4624458D58}.Release-DLL|x64.Build.0 = Release|x64
+		{A2F6CBBA-A553-41B3-A7DE-F26DECCC27F0}.Debug|Win32.ActiveCfg = Debug|Win32
+		{A2F6CBBA-A553-41B3-A7DE-F26DECCC27F0}.Debug|x64.ActiveCfg = Debug|x64
+		{A2F6CBBA-A553-41B3-A7DE-F26DECCC27F0}.Release|Win32.ActiveCfg = Release|Win32
+		{A2F6CBBA-A553-41B3-A7DE-F26DECCC27F0}.Release|x64.ActiveCfg = Release|x64
+		{A2F6CBBA-A553-41B3-A7DE-F26DECCC27F0}.Debug|Win32.Build.0 = Debug|Win32
+		{A2F6CBBA-A553-41B3-A7DE-F26DECCC27F0}.Debug|x64.Build.0 = Debug|x64
+		{A2F6CBBA-A553-41B3-A7DE-F26DECCC27F0}.Release|Win32.Build.0 = Release|Win32
+		{A2F6CBBA-A553-41B3-A7DE-F26DECCC27F0}.Release|x64.Build.0 = Release|x64
+		{A2F6CBBA-A553-41B3-A7DE-F26DECCC27F0}.Debug-DLL|Win32.ActiveCfg = Debug|Win32
+		{A2F6CBBA-A553-41B3-A7DE-F26DECCC27F0}.Debug-DLL|Win32.Build.0 = Debug|Win32
+		{A2F6CBBA-A553-41B3-A7DE-F26DECCC27F0}.Debug-DLL|x64.ActiveCfg = Debug|x64
+		{A2F6CBBA-A553-41B3-A7DE-F26DECCC27F0}.Debug-DLL|x64.Build.0 = Debug|x64
+		{A2F6CBBA-A553-41B3-A7DE-F26DECCC27F0}.Release-DLL|Win32.ActiveCfg = Release|Win32
+		{A2F6CBBA-A553-41B3-A7DE-F26DECCC27F0}.Release-DLL|Win32.Build.0 = Release|Win32
+		{A2F6CBBA-A553-41B3-A7DE-F26DECCC27F0}.Release-DLL|x64.ActiveCfg = Release|x64
+		{A2F6CBBA-A553-41B3-A7DE-F26DECCC27F0}.Release-DLL|x64.Build.0 = Release|x64
 		{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}.Debug|Win32.ActiveCfg = Debug|Win32
 		{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}.Debug|x64.ActiveCfg = Debug|x64
 		{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}.Release|Win32.ActiveCfg = Release|Win32
diff --git a/vsprojects/protoc.props b/vsprojects/protoc.props
index ecaf248..1bdc071 100644
--- a/vsprojects/protoc.props
+++ b/vsprojects/protoc.props
@@ -1 +1 @@
-<?xml version="1.0" encoding="utf-8"?> <Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <ImportGroup Label="PropertySheets" /> <PropertyGroup Label="UserMacros" /> <PropertyGroup /> <ItemDefinitionGroup> <Link> <AdditionalDependencies>libprotoc.lib;%(AdditionalDependencies)</AdditionalDependencies> <AdditionalLibraryDirectories>$(SolutionDir)\..\third_party\protobuf\cmake\$(Configuration);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> </Link> </ItemDefinitionGroup> <ItemGroup /> </Project>
\ No newline at end of file
+<?xml version="1.0" encoding="utf-8"?> <Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <ImportGroup Label="PropertySheets" /> <PropertyGroup Label="UserMacros" /> <PropertyGroup /> <ItemDefinitionGroup> <ClCompile> <DisableSpecificWarnings>4244;4267;%(DisableSpecificWarnings)</DisableSpecificWarnings> </ClCompile> <Link> <AdditionalDependencies>libprotoc.lib;%(AdditionalDependencies)</AdditionalDependencies> <AdditionalLibraryDirectories>$(SolutionDir)\..\third_party\protobuf\cmake\$(Configuration);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> </Link> </ItemDefinitionGroup> <ItemGroup /> </Project>
\ No newline at end of file
diff --git a/vsprojects/vcxproj/gpr/gpr.vcxproj b/vsprojects/vcxproj/gpr/gpr.vcxproj
index e1b3963..dae8e62 100644
--- a/vsprojects/vcxproj/gpr/gpr.vcxproj
+++ b/vsprojects/vcxproj/gpr/gpr.vcxproj
@@ -194,13 +194,14 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\profiling\timers.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\support\block_annotate.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\support\env.h" />
-    <ClInclude Include="$(SolutionDir)\..\src\core\support\file.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\support\load_file.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\support\murmur_hash.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\support\stack_lockfree.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\support\string.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\support\string_win32.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\support\thd_internal.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\support\time_precise.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\support\tmpfile.h" />
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="$(SolutionDir)\..\src\core\profiling\basic_timers.c">
@@ -227,16 +228,12 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\support\env_win32.c">
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\support\file.c">
-    </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\support\file_posix.c">
-    </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\support\file_win32.c">
-    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\support\histogram.c">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\support\host_port.c">
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\support\load_file.c">
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\support\log.c">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\support\log_android.c">
@@ -287,6 +284,10 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\support\tls_pthread.c">
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\support\tmpfile_posix.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\support\tmpfile_win32.c">
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\support\wrap_memcpy.c">
     </ClCompile>
   </ItemGroup>
diff --git a/vsprojects/vcxproj/gpr/gpr.vcxproj.filters b/vsprojects/vcxproj/gpr/gpr.vcxproj.filters
index aedba93..055b29f 100644
--- a/vsprojects/vcxproj/gpr/gpr.vcxproj.filters
+++ b/vsprojects/vcxproj/gpr/gpr.vcxproj.filters
@@ -37,21 +37,15 @@
     <ClCompile Include="$(SolutionDir)\..\src\core\support\env_win32.c">
       <Filter>src\core\support</Filter>
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\support\file.c">
-      <Filter>src\core\support</Filter>
-    </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\support\file_posix.c">
-      <Filter>src\core\support</Filter>
-    </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\support\file_win32.c">
-      <Filter>src\core\support</Filter>
-    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\support\histogram.c">
       <Filter>src\core\support</Filter>
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\support\host_port.c">
       <Filter>src\core\support</Filter>
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\support\load_file.c">
+      <Filter>src\core\support</Filter>
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\support\log.c">
       <Filter>src\core\support</Filter>
     </ClCompile>
@@ -127,6 +121,12 @@
     <ClCompile Include="$(SolutionDir)\..\src\core\support\tls_pthread.c">
       <Filter>src\core\support</Filter>
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\support\tmpfile_posix.c">
+      <Filter>src\core\support</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\support\tmpfile_win32.c">
+      <Filter>src\core\support</Filter>
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\support\wrap_memcpy.c">
       <Filter>src\core\support</Filter>
     </ClCompile>
@@ -269,7 +269,7 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\support\env.h">
       <Filter>src\core\support</Filter>
     </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\src\core\support\file.h">
+    <ClInclude Include="$(SolutionDir)\..\src\core\support\load_file.h">
       <Filter>src\core\support</Filter>
     </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\src\core\support\murmur_hash.h">
@@ -290,6 +290,9 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\support\time_precise.h">
       <Filter>src\core\support</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\support\tmpfile.h">
+      <Filter>src\core\support</Filter>
+    </ClInclude>
   </ItemGroup>
 
   <ItemGroup>
diff --git a/vsprojects/vcxproj/grpc++/grpc++.vcxproj b/vsprojects/vcxproj/grpc++/grpc++.vcxproj
index 098f67e..64c6a24 100644
--- a/vsprojects/vcxproj/grpc++/grpc++.vcxproj
+++ b/vsprojects/vcxproj/grpc++/grpc++.vcxproj
@@ -341,8 +341,6 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\cpp\client\insecure_credentials.cc">
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\cpp\common\alarm.cc">
-    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\cpp\common\call.cc">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\cpp\common\channel_arguments.cc">
@@ -351,6 +349,8 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\cpp\common\rpc_method.cc">
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\cpp\proto\proto_serializer.cc">
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\cpp\proto\proto_utils.cc">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\cpp\server\async_generic_service.cc">
diff --git a/vsprojects/vcxproj/grpc++/grpc++.vcxproj.filters b/vsprojects/vcxproj/grpc++/grpc++.vcxproj.filters
index a827051..8dde694 100644
--- a/vsprojects/vcxproj/grpc++/grpc++.vcxproj.filters
+++ b/vsprojects/vcxproj/grpc++/grpc++.vcxproj.filters
@@ -43,9 +43,6 @@
     <ClCompile Include="$(SolutionDir)\..\src\cpp\client\insecure_credentials.cc">
       <Filter>src\cpp\client</Filter>
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\cpp\common\alarm.cc">
-      <Filter>src\cpp\common</Filter>
-    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\cpp\common\call.cc">
       <Filter>src\cpp\common</Filter>
     </ClCompile>
@@ -58,6 +55,9 @@
     <ClCompile Include="$(SolutionDir)\..\src\cpp\common\rpc_method.cc">
       <Filter>src\cpp\common</Filter>
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\cpp\proto\proto_serializer.cc">
+      <Filter>src\cpp\proto</Filter>
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\cpp\proto\proto_utils.cc">
       <Filter>src\cpp\proto</Filter>
     </ClCompile>
diff --git a/vsprojects/vcxproj/grpc++_test_util/grpc++_test_util.vcxproj b/vsprojects/vcxproj/grpc++_test_util/grpc++_test_util.vcxproj
index 3d35371..33860af 100644
--- a/vsprojects/vcxproj/grpc++_test_util/grpc++_test_util.vcxproj
+++ b/vsprojects/vcxproj/grpc++_test_util/grpc++_test_util.vcxproj
@@ -153,6 +153,7 @@
     <ClInclude Include="$(SolutionDir)\..\test\cpp\util\create_test_channel.h" />
     <ClInclude Include="$(SolutionDir)\..\test\cpp\util\string_ref_helper.h" />
     <ClInclude Include="$(SolutionDir)\..\test\cpp\util\subprocess.h" />
+    <ClInclude Include="$(SolutionDir)\..\test\cpp\util\test_credentials_provider.h" />
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="$(SolutionDir)\..\src\proto\grpc\testing\echo_messages.pb.cc">
@@ -191,6 +192,8 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\test\cpp\util\subprocess.cc">
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\test\cpp\util\test_credentials_provider.cc">
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\grpc++\grpc++.vcxproj">
diff --git a/vsprojects/vcxproj/grpc++_test_util/grpc++_test_util.vcxproj.filters b/vsprojects/vcxproj/grpc++_test_util/grpc++_test_util.vcxproj.filters
index 27ac675..b35ba1f 100644
--- a/vsprojects/vcxproj/grpc++_test_util/grpc++_test_util.vcxproj.filters
+++ b/vsprojects/vcxproj/grpc++_test_util/grpc++_test_util.vcxproj.filters
@@ -28,6 +28,9 @@
     <ClCompile Include="$(SolutionDir)\..\test\cpp\util\subprocess.cc">
       <Filter>test\cpp\util</Filter>
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\test\cpp\util\test_credentials_provider.cc">
+      <Filter>test\cpp\util</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="$(SolutionDir)\..\test\cpp\end2end\test_service_impl.h">
@@ -48,6 +51,9 @@
     <ClInclude Include="$(SolutionDir)\..\test\cpp\util\subprocess.h">
       <Filter>test\cpp\util</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\test\cpp\util\test_credentials_provider.h">
+      <Filter>test\cpp\util</Filter>
+    </ClInclude>
   </ItemGroup>
 
   <ItemGroup>
diff --git a/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj b/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj
index d5dedfa..6094f41 100644
--- a/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj
+++ b/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj
@@ -326,8 +326,6 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\cpp\client\insecure_credentials.cc">
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\cpp\common\alarm.cc">
-    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\cpp\common\call.cc">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\cpp\common\channel_arguments.cc">
@@ -336,6 +334,8 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\cpp\common\rpc_method.cc">
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\cpp\proto\proto_serializer.cc">
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\cpp\proto\proto_utils.cc">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\cpp\server\async_generic_service.cc">
diff --git a/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj.filters b/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj.filters
index 0b713d2..5f242ba 100644
--- a/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj.filters
+++ b/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj.filters
@@ -25,9 +25,6 @@
     <ClCompile Include="$(SolutionDir)\..\src\cpp\client\insecure_credentials.cc">
       <Filter>src\cpp\client</Filter>
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\cpp\common\alarm.cc">
-      <Filter>src\cpp\common</Filter>
-    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\cpp\common\call.cc">
       <Filter>src\cpp\common</Filter>
     </ClCompile>
@@ -40,6 +37,9 @@
     <ClCompile Include="$(SolutionDir)\..\src\cpp\common\rpc_method.cc">
       <Filter>src\cpp\common</Filter>
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\cpp\proto\proto_serializer.cc">
+      <Filter>src\cpp\proto</Filter>
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\cpp\proto\proto_utils.cc">
       <Filter>src\cpp\proto</Filter>
     </ClCompile>
diff --git a/vsprojects/vcxproj/grpc/grpc.vcxproj b/vsprojects/vcxproj/grpc/grpc.vcxproj
index 8d3154f..7ba49d1 100644
--- a/vsprojects/vcxproj/grpc/grpc.vcxproj
+++ b/vsprojects/vcxproj/grpc/grpc.vcxproj
@@ -276,20 +276,6 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\census.h" />
   </ItemGroup>
   <ItemGroup>
-    <ClInclude Include="$(SolutionDir)\..\src\core\security\auth_filters.h" />
-    <ClInclude Include="$(SolutionDir)\..\src\core\security\base64.h" />
-    <ClInclude Include="$(SolutionDir)\..\src\core\security\credentials.h" />
-    <ClInclude Include="$(SolutionDir)\..\src\core\security\handshake.h" />
-    <ClInclude Include="$(SolutionDir)\..\src\core\security\json_token.h" />
-    <ClInclude Include="$(SolutionDir)\..\src\core\security\jwt_verifier.h" />
-    <ClInclude Include="$(SolutionDir)\..\src\core\security\secure_endpoint.h" />
-    <ClInclude Include="$(SolutionDir)\..\src\core\security\security_connector.h" />
-    <ClInclude Include="$(SolutionDir)\..\src\core\security\security_context.h" />
-    <ClInclude Include="$(SolutionDir)\..\src\core\tsi\fake_transport_security.h" />
-    <ClInclude Include="$(SolutionDir)\..\src\core\tsi\ssl_transport_security.h" />
-    <ClInclude Include="$(SolutionDir)\..\src\core\tsi\ssl_types.h" />
-    <ClInclude Include="$(SolutionDir)\..\src\core\tsi\transport_security.h" />
-    <ClInclude Include="$(SolutionDir)\..\src\core\tsi\transport_security_interface.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\census\grpc_filter.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\channel\channel_args.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\channel\channel_stack.h" />
@@ -304,6 +290,7 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\client_config\client_config.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\client_config\connector.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\client_config\initial_connect_string.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\client_config\lb_policies\load_balancer_api.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\client_config\lb_policies\pick_first.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\client_config\lb_policies\round_robin.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\client_config\lb_policy.h" />
@@ -354,7 +341,6 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\iomgr\time_averaged_stats.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\iomgr\timer.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\iomgr\timer_heap.h" />
-    <ClInclude Include="$(SolutionDir)\..\src\core\iomgr\timer_internal.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\iomgr\udp_server.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\iomgr\wakeup_fd_pipe.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\iomgr\wakeup_fd_posix.h" />
@@ -365,6 +351,7 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\json\json_common.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\json\json_reader.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\json\json_writer.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\proto\grpc\lb\v0\load_balancer.pb.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\statistics\census_interface.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\statistics\census_rpc_stats.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\surface\api_trace.h" />
@@ -404,53 +391,29 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\transport\static_metadata.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\transport\transport.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\transport\transport_impl.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\security\auth_filters.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\security\b64.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\security\credentials.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\security\handshake.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\security\json_token.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\security\jwt_verifier.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\security\secure_endpoint.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\security\security_connector.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\security\security_context.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\tsi\fake_transport_security.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\tsi\ssl_transport_security.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\tsi\ssl_types.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\tsi\transport_security.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\tsi\transport_security_interface.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\census\aggregation.h" />
-    <ClInclude Include="$(SolutionDir)\..\src\core\census\log.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\census\mlog.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\census\rpc_metric_id.h" />
+    <ClInclude Include="$(SolutionDir)\..\third_party\nanopb\pb.h" />
+    <ClInclude Include="$(SolutionDir)\..\third_party\nanopb\pb_common.h" />
+    <ClInclude Include="$(SolutionDir)\..\third_party\nanopb\pb_decode.h" />
+    <ClInclude Include="$(SolutionDir)\..\third_party\nanopb\pb_encode.h" />
   </ItemGroup>
   <ItemGroup>
-    <ClCompile Include="$(SolutionDir)\..\src\core\httpcli\httpcli_security_connector.c">
-    </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\security\base64.c">
-    </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\security\client_auth_filter.c">
-    </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\security\credentials.c">
-    </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\security\credentials_metadata.c">
-    </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\security\credentials_posix.c">
-    </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\security\credentials_win32.c">
-    </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\security\google_default_credentials.c">
-    </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\security\handshake.c">
-    </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\security\json_token.c">
-    </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\security\jwt_verifier.c">
-    </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\security\secure_endpoint.c">
-    </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\security\security_connector.c">
-    </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\security\security_context.c">
-    </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\security\server_auth_filter.c">
-    </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\security\server_secure_chttp2.c">
-    </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\surface\init_secure.c">
-    </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\surface\secure_channel_create.c">
-    </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\tsi\fake_transport_security.c">
-    </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\tsi\ssl_transport_security.c">
-    </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\tsi\transport_security.c">
-    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\census\grpc_context.c">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\census\grpc_filter.c">
@@ -481,6 +444,8 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\client_config\initial_connect_string.c">
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\client_config\lb_policies\load_balancer_api.c">
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\client_config\lb_policies\pick_first.c">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\client_config\lb_policies\round_robin.c">
@@ -509,7 +474,7 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\client_config\uri_parser.c">
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\compression\algorithm.c">
+    <ClCompile Include="$(SolutionDir)\..\src\core\compression\compression_algorithm.c">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\compression\message_compress.c">
     </ClCompile>
@@ -609,6 +574,8 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\json\json_writer.c">
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\proto\grpc\lb\v0\load_balancer.pb.c">
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\surface\alarm.c">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\surface\api_trace.c">
@@ -707,11 +674,53 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\transport\transport_op_string.c">
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\httpcli\httpcli_security_connector.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\security\b64.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\security\client_auth_filter.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\security\credentials.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\security\credentials_metadata.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\security\credentials_posix.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\security\credentials_win32.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\security\google_default_credentials.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\security\handshake.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\security\json_token.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\security\jwt_verifier.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\security\secure_endpoint.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\security\security_connector.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\security\security_context.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\security\server_auth_filter.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\security\server_secure_chttp2.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\surface\init_secure.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\surface\secure_channel_create.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\tsi\fake_transport_security.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\tsi\ssl_transport_security.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\tsi\transport_security.c">
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\census\context.c">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\census\initialize.c">
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\census\log.c">
+    <ClCompile Include="$(SolutionDir)\..\src\core\census\mlog.c">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\census\operation.c">
     </ClCompile>
@@ -719,6 +728,12 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\census\tracing.c">
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\third_party\nanopb\pb_common.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\third_party\nanopb\pb_decode.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\third_party\nanopb\pb_encode.c">
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\gpr\gpr.vcxproj">
diff --git a/vsprojects/vcxproj/grpc/grpc.vcxproj.filters b/vsprojects/vcxproj/grpc/grpc.vcxproj.filters
index a6309fe..60a9f25 100644
--- a/vsprojects/vcxproj/grpc/grpc.vcxproj.filters
+++ b/vsprojects/vcxproj/grpc/grpc.vcxproj.filters
@@ -1,69 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
   <ItemGroup>
-    <ClCompile Include="$(SolutionDir)\..\src\core\httpcli\httpcli_security_connector.c">
-      <Filter>src\core\httpcli</Filter>
-    </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\security\base64.c">
-      <Filter>src\core\security</Filter>
-    </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\security\client_auth_filter.c">
-      <Filter>src\core\security</Filter>
-    </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\security\credentials.c">
-      <Filter>src\core\security</Filter>
-    </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\security\credentials_metadata.c">
-      <Filter>src\core\security</Filter>
-    </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\security\credentials_posix.c">
-      <Filter>src\core\security</Filter>
-    </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\security\credentials_win32.c">
-      <Filter>src\core\security</Filter>
-    </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\security\google_default_credentials.c">
-      <Filter>src\core\security</Filter>
-    </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\security\handshake.c">
-      <Filter>src\core\security</Filter>
-    </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\security\json_token.c">
-      <Filter>src\core\security</Filter>
-    </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\security\jwt_verifier.c">
-      <Filter>src\core\security</Filter>
-    </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\security\secure_endpoint.c">
-      <Filter>src\core\security</Filter>
-    </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\security\security_connector.c">
-      <Filter>src\core\security</Filter>
-    </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\security\security_context.c">
-      <Filter>src\core\security</Filter>
-    </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\security\server_auth_filter.c">
-      <Filter>src\core\security</Filter>
-    </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\security\server_secure_chttp2.c">
-      <Filter>src\core\security</Filter>
-    </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\surface\init_secure.c">
-      <Filter>src\core\surface</Filter>
-    </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\surface\secure_channel_create.c">
-      <Filter>src\core\surface</Filter>
-    </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\tsi\fake_transport_security.c">
-      <Filter>src\core\tsi</Filter>
-    </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\tsi\ssl_transport_security.c">
-      <Filter>src\core\tsi</Filter>
-    </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\tsi\transport_security.c">
-      <Filter>src\core\tsi</Filter>
-    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\census\grpc_context.c">
       <Filter>src\core\census</Filter>
     </ClCompile>
@@ -109,6 +46,9 @@
     <ClCompile Include="$(SolutionDir)\..\src\core\client_config\initial_connect_string.c">
       <Filter>src\core\client_config</Filter>
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\client_config\lb_policies\load_balancer_api.c">
+      <Filter>src\core\client_config\lb_policies</Filter>
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\client_config\lb_policies\pick_first.c">
       <Filter>src\core\client_config\lb_policies</Filter>
     </ClCompile>
@@ -151,7 +91,7 @@
     <ClCompile Include="$(SolutionDir)\..\src\core\client_config\uri_parser.c">
       <Filter>src\core\client_config</Filter>
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\compression\algorithm.c">
+    <ClCompile Include="$(SolutionDir)\..\src\core\compression\compression_algorithm.c">
       <Filter>src\core\compression</Filter>
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\compression\message_compress.c">
@@ -301,6 +241,9 @@
     <ClCompile Include="$(SolutionDir)\..\src\core\json\json_writer.c">
       <Filter>src\core\json</Filter>
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\proto\grpc\lb\v0\load_balancer.pb.c">
+      <Filter>src\core\proto\grpc\lb\v0</Filter>
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\surface\alarm.c">
       <Filter>src\core\surface</Filter>
     </ClCompile>
@@ -448,13 +391,76 @@
     <ClCompile Include="$(SolutionDir)\..\src\core\transport\transport_op_string.c">
       <Filter>src\core\transport</Filter>
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\httpcli\httpcli_security_connector.c">
+      <Filter>src\core\httpcli</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\security\b64.c">
+      <Filter>src\core\security</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\security\client_auth_filter.c">
+      <Filter>src\core\security</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\security\credentials.c">
+      <Filter>src\core\security</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\security\credentials_metadata.c">
+      <Filter>src\core\security</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\security\credentials_posix.c">
+      <Filter>src\core\security</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\security\credentials_win32.c">
+      <Filter>src\core\security</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\security\google_default_credentials.c">
+      <Filter>src\core\security</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\security\handshake.c">
+      <Filter>src\core\security</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\security\json_token.c">
+      <Filter>src\core\security</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\security\jwt_verifier.c">
+      <Filter>src\core\security</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\security\secure_endpoint.c">
+      <Filter>src\core\security</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\security\security_connector.c">
+      <Filter>src\core\security</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\security\security_context.c">
+      <Filter>src\core\security</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\security\server_auth_filter.c">
+      <Filter>src\core\security</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\security\server_secure_chttp2.c">
+      <Filter>src\core\security</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\surface\init_secure.c">
+      <Filter>src\core\surface</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\surface\secure_channel_create.c">
+      <Filter>src\core\surface</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\tsi\fake_transport_security.c">
+      <Filter>src\core\tsi</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\tsi\ssl_transport_security.c">
+      <Filter>src\core\tsi</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\tsi\transport_security.c">
+      <Filter>src\core\tsi</Filter>
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\census\context.c">
       <Filter>src\core\census</Filter>
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\census\initialize.c">
       <Filter>src\core\census</Filter>
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\census\log.c">
+    <ClCompile Include="$(SolutionDir)\..\src\core\census\mlog.c">
       <Filter>src\core\census</Filter>
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\census\operation.c">
@@ -466,6 +472,15 @@
     <ClCompile Include="$(SolutionDir)\..\src\core\census\tracing.c">
       <Filter>src\core\census</Filter>
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\third_party\nanopb\pb_common.c">
+      <Filter>third_party\nanopb</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\third_party\nanopb\pb_decode.c">
+      <Filter>third_party\nanopb</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\third_party\nanopb\pb_encode.c">
+      <Filter>third_party\nanopb</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="$(SolutionDir)\..\include\grpc\grpc_security.h">
@@ -491,48 +506,6 @@
     </ClInclude>
   </ItemGroup>
   <ItemGroup>
-    <ClInclude Include="$(SolutionDir)\..\src\core\security\auth_filters.h">
-      <Filter>src\core\security</Filter>
-    </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\src\core\security\base64.h">
-      <Filter>src\core\security</Filter>
-    </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\src\core\security\credentials.h">
-      <Filter>src\core\security</Filter>
-    </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\src\core\security\handshake.h">
-      <Filter>src\core\security</Filter>
-    </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\src\core\security\json_token.h">
-      <Filter>src\core\security</Filter>
-    </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\src\core\security\jwt_verifier.h">
-      <Filter>src\core\security</Filter>
-    </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\src\core\security\secure_endpoint.h">
-      <Filter>src\core\security</Filter>
-    </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\src\core\security\security_connector.h">
-      <Filter>src\core\security</Filter>
-    </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\src\core\security\security_context.h">
-      <Filter>src\core\security</Filter>
-    </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\src\core\tsi\fake_transport_security.h">
-      <Filter>src\core\tsi</Filter>
-    </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\src\core\tsi\ssl_transport_security.h">
-      <Filter>src\core\tsi</Filter>
-    </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\src\core\tsi\ssl_types.h">
-      <Filter>src\core\tsi</Filter>
-    </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\src\core\tsi\transport_security.h">
-      <Filter>src\core\tsi</Filter>
-    </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\src\core\tsi\transport_security_interface.h">
-      <Filter>src\core\tsi</Filter>
-    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\src\core\census\grpc_filter.h">
       <Filter>src\core\census</Filter>
     </ClInclude>
@@ -575,6 +548,9 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\client_config\initial_connect_string.h">
       <Filter>src\core\client_config</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\client_config\lb_policies\load_balancer_api.h">
+      <Filter>src\core\client_config\lb_policies</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\src\core\client_config\lb_policies\pick_first.h">
       <Filter>src\core\client_config\lb_policies</Filter>
     </ClInclude>
@@ -725,9 +701,6 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\iomgr\timer_heap.h">
       <Filter>src\core\iomgr</Filter>
     </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\src\core\iomgr\timer_internal.h">
-      <Filter>src\core\iomgr</Filter>
-    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\src\core\iomgr\udp_server.h">
       <Filter>src\core\iomgr</Filter>
     </ClInclude>
@@ -758,6 +731,9 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\json\json_writer.h">
       <Filter>src\core\json</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\proto\grpc\lb\v0\load_balancer.pb.h">
+      <Filter>src\core\proto\grpc\lb\v0</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\src\core\statistics\census_interface.h">
       <Filter>src\core\statistics</Filter>
     </ClInclude>
@@ -875,15 +851,69 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\transport\transport_impl.h">
       <Filter>src\core\transport</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\security\auth_filters.h">
+      <Filter>src\core\security</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\security\b64.h">
+      <Filter>src\core\security</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\security\credentials.h">
+      <Filter>src\core\security</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\security\handshake.h">
+      <Filter>src\core\security</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\security\json_token.h">
+      <Filter>src\core\security</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\security\jwt_verifier.h">
+      <Filter>src\core\security</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\security\secure_endpoint.h">
+      <Filter>src\core\security</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\security\security_connector.h">
+      <Filter>src\core\security</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\security\security_context.h">
+      <Filter>src\core\security</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\tsi\fake_transport_security.h">
+      <Filter>src\core\tsi</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\tsi\ssl_transport_security.h">
+      <Filter>src\core\tsi</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\tsi\ssl_types.h">
+      <Filter>src\core\tsi</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\tsi\transport_security.h">
+      <Filter>src\core\tsi</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\tsi\transport_security_interface.h">
+      <Filter>src\core\tsi</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\src\core\census\aggregation.h">
       <Filter>src\core\census</Filter>
     </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\src\core\census\log.h">
+    <ClInclude Include="$(SolutionDir)\..\src\core\census\mlog.h">
       <Filter>src\core\census</Filter>
     </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\src\core\census\rpc_metric_id.h">
       <Filter>src\core\census</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\third_party\nanopb\pb.h">
+      <Filter>third_party\nanopb</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\third_party\nanopb\pb_common.h">
+      <Filter>third_party\nanopb</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\third_party\nanopb\pb_decode.h">
+      <Filter>third_party\nanopb</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\third_party\nanopb\pb_encode.h">
+      <Filter>third_party\nanopb</Filter>
+    </ClInclude>
   </ItemGroup>
 
   <ItemGroup>
@@ -929,6 +959,18 @@
     <Filter Include="src\core\json">
       <UniqueIdentifier>{e665cc0e-b994-d7c5-cc18-2007392019f0}</UniqueIdentifier>
     </Filter>
+    <Filter Include="src\core\proto">
+      <UniqueIdentifier>{1ff04466-0905-8a5d-d6f4-7ff2df4c13b5}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\core\proto\grpc">
+      <UniqueIdentifier>{7c7ad0b3-bf85-5bd3-e0c8-4f5468a8e2e6}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\core\proto\grpc\lb">
+      <UniqueIdentifier>{3d533dad-8100-e8a3-b7c3-1fc13a4d60da}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\core\proto\grpc\lb\v0">
+      <UniqueIdentifier>{0ffcf868-7617-5fed-b6ce-2162d9d09148}</UniqueIdentifier>
+    </Filter>
     <Filter Include="src\core\security">
       <UniqueIdentifier>{1d850ac6-e639-4eab-5338-4ba40272fcc9}</UniqueIdentifier>
     </Filter>
@@ -947,6 +989,12 @@
     <Filter Include="src\core\tsi">
       <UniqueIdentifier>{0b0f9ab1-efa4-7f03-e446-6fb9b5227e84}</UniqueIdentifier>
     </Filter>
+    <Filter Include="third_party">
+      <UniqueIdentifier>{aaab30a4-2a15-732e-c141-3fbc0f0f5a7a}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="third_party\nanopb">
+      <UniqueIdentifier>{93d6596d-330c-1d27-6f84-3c840e57869e}</UniqueIdentifier>
+    </Filter>
   </ItemGroup>
 </Project>
 
diff --git a/vsprojects/vcxproj/test/grpc_base64_test/grpc_base64_test.vcxproj b/vsprojects/vcxproj/grpc_dll/grpc_dll.vcxproj
similarity index 92%
copy from vsprojects/vcxproj/test/grpc_base64_test/grpc_base64_test.vcxproj
copy to vsprojects/vcxproj/grpc_dll/grpc_dll.vcxproj
index 3e49ac8..cafc951 100644
--- a/vsprojects/vcxproj/test/grpc_base64_test/grpc_base64_test.vcxproj
+++ b/vsprojects/vcxproj/grpc_dll/grpc_dll.vcxproj
@@ -20,7 +20,7 @@
     </ProjectConfiguration>
   </ItemGroup>
   <PropertyGroup Label="Globals">
-    <ProjectGuid>{759A2BB1-DA1B-196C-94A3-98687BBC9F36}</ProjectGuid>
+    <ProjectGuid>{A2F6CBBA-A553-41B3-A7DE-F26DECCC27F0}</ProjectGuid>
     <IgnoreWarnIntDirInTempDetected>true</IgnoreWarnIntDirInTempDetected>
     <IntDir>$(SolutionDir)IntDir\$(MSBuildProjectName)\</IntDir>
   </PropertyGroup>
@@ -38,12 +38,12 @@
     <PlatformToolset>v140</PlatformToolset>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)'=='Debug'" Label="Configuration">
-    <ConfigurationType>Application</ConfigurationType>
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
     <UseDebugLibraries>true</UseDebugLibraries>
     <CharacterSet>Unicode</CharacterSet>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)'=='Release'" Label="Configuration">
-    <ConfigurationType>Application</ConfigurationType>
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
     <UseDebugLibraries>false</UseDebugLibraries>
     <WholeProgramOptimization>true</WholeProgramOptimization>
     <CharacterSet>Unicode</CharacterSet>
@@ -60,14 +60,14 @@
   </ImportGroup>
   <PropertyGroup Label="UserMacros" />
   <PropertyGroup Condition="'$(Configuration)'=='Debug'">
-    <TargetName>grpc_base64_test</TargetName>
+    <TargetName>grpc_dll</TargetName>
     <Linkage-grpc_dependencies_zlib>static</Linkage-grpc_dependencies_zlib>
     <Configuration-grpc_dependencies_zlib>Debug</Configuration-grpc_dependencies_zlib>
     <Linkage-grpc_dependencies_openssl>static</Linkage-grpc_dependencies_openssl>
     <Configuration-grpc_dependencies_openssl>Debug</Configuration-grpc_dependencies_openssl>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)'=='Release'">
-    <TargetName>grpc_base64_test</TargetName>
+    <TargetName>grpc_dll</TargetName>
     <Linkage-grpc_dependencies_zlib>static</Linkage-grpc_dependencies_zlib>
     <Configuration-grpc_dependencies_zlib>Release</Configuration-grpc_dependencies_zlib>
     <Linkage-grpc_dependencies_openssl>static</Linkage-grpc_dependencies_openssl>
@@ -86,9 +86,10 @@
       <MinimalRebuild Condition="$(Jenkins)">false</MinimalRebuild>
     </ClCompile>
     <Link>
-      <SubSystem>Console</SubSystem>
+      <SubSystem>Windows</SubSystem>
       <GenerateDebugInformation Condition="!$(Jenkins)">true</GenerateDebugInformation>
       <GenerateDebugInformation Condition="$(Jenkins)">false</GenerateDebugInformation>
+      <ModuleDefinitionFile>$(SolutionDir)\..\grpc.def</ModuleDefinitionFile>
     </Link>
   </ItemDefinitionGroup>
 
@@ -105,9 +106,10 @@
       <MinimalRebuild Condition="$(Jenkins)">false</MinimalRebuild>
     </ClCompile>
     <Link>
-      <SubSystem>Console</SubSystem>
+      <SubSystem>Windows</SubSystem>
       <GenerateDebugInformation Condition="!$(Jenkins)">true</GenerateDebugInformation>
       <GenerateDebugInformation Condition="$(Jenkins)">false</GenerateDebugInformation>
+      <ModuleDefinitionFile>$(SolutionDir)\..\grpc.def</ModuleDefinitionFile>
     </Link>
   </ItemDefinitionGroup>
 
@@ -126,9 +128,10 @@
       <MinimalRebuild Condition="$(Jenkins)">false</MinimalRebuild>
     </ClCompile>
     <Link>
-      <SubSystem>Console</SubSystem>
+      <SubSystem>Windows</SubSystem>
       <GenerateDebugInformation Condition="!$(Jenkins)">true</GenerateDebugInformation>
       <GenerateDebugInformation Condition="$(Jenkins)">false</GenerateDebugInformation>
+      <ModuleDefinitionFile>$(SolutionDir)\..\grpc.def</ModuleDefinitionFile>
       <EnableCOMDATFolding>true</EnableCOMDATFolding>
       <OptimizeReferences>true</OptimizeReferences>
     </Link>
@@ -149,31 +152,29 @@
       <MinimalRebuild Condition="$(Jenkins)">false</MinimalRebuild>
     </ClCompile>
     <Link>
-      <SubSystem>Console</SubSystem>
+      <SubSystem>Windows</SubSystem>
       <GenerateDebugInformation Condition="!$(Jenkins)">true</GenerateDebugInformation>
       <GenerateDebugInformation Condition="$(Jenkins)">false</GenerateDebugInformation>
+      <ModuleDefinitionFile>$(SolutionDir)\..\grpc.def</ModuleDefinitionFile>
       <EnableCOMDATFolding>true</EnableCOMDATFolding>
       <OptimizeReferences>true</OptimizeReferences>
     </Link>
   </ItemDefinitionGroup>
 
   <ItemGroup>
-    <ClCompile Include="$(SolutionDir)\..\test\core\security\base64_test.c">
+    <None Include="$(SolutionDir)\..\grpc.def" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="$(SolutionDir)\..\vsprojects\dummy.c">
     </ClCompile>
   </ItemGroup>
   <ItemGroup>
-    <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\grpc_test_util\grpc_test_util.vcxproj">
-      <Project>{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}</Project>
+    <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\gpr\gpr.vcxproj">
+      <Project>{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}</Project>
     </ProjectReference>
     <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\grpc\grpc.vcxproj">
       <Project>{29D16885-7228-4C31-81ED-5F9187C7F2A9}</Project>
     </ProjectReference>
-    <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\gpr_test_util\gpr_test_util.vcxproj">
-      <Project>{EAB0A629-17A9-44DB-B5FF-E91A721FE037}</Project>
-    </ProjectReference>
-    <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\gpr\gpr.vcxproj">
-      <Project>{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}</Project>
-    </ProjectReference>
   </ItemGroup>
   <ItemGroup>
     <None Include="packages.config" />
diff --git a/vsprojects/vcxproj/grpc_dll/grpc_dll.vcxproj.filters b/vsprojects/vcxproj/grpc_dll/grpc_dll.vcxproj.filters
new file mode 100644
index 0000000..8493ace
--- /dev/null
+++ b/vsprojects/vcxproj/grpc_dll/grpc_dll.vcxproj.filters
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup>
+    <None Include="$(SolutionDir)\..\grpc.def" />
+  </ItemGroup>
+
+  <ItemGroup>
+  </ItemGroup>
+</Project>
+
diff --git a/vsprojects/vcxproj/grpc_plugin_support/grpc_plugin_support.vcxproj b/vsprojects/vcxproj/grpc_plugin_support/grpc_plugin_support.vcxproj
index 5a5a1c4..f5abfdd 100644
--- a/vsprojects/vcxproj/grpc_plugin_support/grpc_plugin_support.vcxproj
+++ b/vsprojects/vcxproj/grpc_plugin_support/grpc_plugin_support.vcxproj
@@ -53,6 +53,7 @@
   <ImportGroup Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
     <Import Project="$(SolutionDir)\..\vsprojects\global.props" />
+    <Import Project="$(SolutionDir)\..\vsprojects\protoc.props" />
     <Import Project="$(SolutionDir)\..\vsprojects\winsock.props" />
   </ImportGroup>
   <PropertyGroup Label="UserMacros" />
diff --git a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj
index bf4814f..4a06e2d 100644
--- a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj
+++ b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj
@@ -280,6 +280,7 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\client_config\client_config.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\client_config\connector.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\client_config\initial_connect_string.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\client_config\lb_policies\load_balancer_api.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\client_config\lb_policies\pick_first.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\client_config\lb_policies\round_robin.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\client_config\lb_policy.h" />
@@ -330,7 +331,6 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\iomgr\time_averaged_stats.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\iomgr\timer.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\iomgr\timer_heap.h" />
-    <ClInclude Include="$(SolutionDir)\..\src\core\iomgr\timer_internal.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\iomgr\udp_server.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\iomgr\wakeup_fd_pipe.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\iomgr\wakeup_fd_posix.h" />
@@ -341,6 +341,7 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\json\json_common.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\json\json_reader.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\json\json_writer.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\proto\grpc\lb\v0\load_balancer.pb.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\statistics\census_interface.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\statistics\census_rpc_stats.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\surface\api_trace.h" />
@@ -381,8 +382,12 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\transport\transport.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\transport\transport_impl.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\census\aggregation.h" />
-    <ClInclude Include="$(SolutionDir)\..\src\core\census\log.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\census\mlog.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\census\rpc_metric_id.h" />
+    <ClInclude Include="$(SolutionDir)\..\third_party\nanopb\pb.h" />
+    <ClInclude Include="$(SolutionDir)\..\third_party\nanopb\pb_common.h" />
+    <ClInclude Include="$(SolutionDir)\..\third_party\nanopb\pb_decode.h" />
+    <ClInclude Include="$(SolutionDir)\..\third_party\nanopb\pb_encode.h" />
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="$(SolutionDir)\..\src\core\surface\init_unsecure.c">
@@ -417,6 +422,8 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\client_config\initial_connect_string.c">
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\client_config\lb_policies\load_balancer_api.c">
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\client_config\lb_policies\pick_first.c">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\client_config\lb_policies\round_robin.c">
@@ -445,7 +452,7 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\client_config\uri_parser.c">
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\compression\algorithm.c">
+    <ClCompile Include="$(SolutionDir)\..\src\core\compression\compression_algorithm.c">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\compression\message_compress.c">
     </ClCompile>
@@ -545,6 +552,8 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\json\json_writer.c">
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\proto\grpc\lb\v0\load_balancer.pb.c">
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\surface\alarm.c">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\surface\api_trace.c">
@@ -647,7 +656,7 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\census\initialize.c">
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\census\log.c">
+    <ClCompile Include="$(SolutionDir)\..\src\core\census\mlog.c">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\census\operation.c">
     </ClCompile>
@@ -655,6 +664,12 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\census\tracing.c">
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\third_party\nanopb\pb_common.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\third_party\nanopb\pb_decode.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\third_party\nanopb\pb_encode.c">
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\gpr\gpr.vcxproj">
diff --git a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters
index 4989913..cd67a32 100644
--- a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters
+++ b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters
@@ -49,6 +49,9 @@
     <ClCompile Include="$(SolutionDir)\..\src\core\client_config\initial_connect_string.c">
       <Filter>src\core\client_config</Filter>
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\client_config\lb_policies\load_balancer_api.c">
+      <Filter>src\core\client_config\lb_policies</Filter>
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\client_config\lb_policies\pick_first.c">
       <Filter>src\core\client_config\lb_policies</Filter>
     </ClCompile>
@@ -91,7 +94,7 @@
     <ClCompile Include="$(SolutionDir)\..\src\core\client_config\uri_parser.c">
       <Filter>src\core\client_config</Filter>
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\compression\algorithm.c">
+    <ClCompile Include="$(SolutionDir)\..\src\core\compression\compression_algorithm.c">
       <Filter>src\core\compression</Filter>
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\compression\message_compress.c">
@@ -241,6 +244,9 @@
     <ClCompile Include="$(SolutionDir)\..\src\core\json\json_writer.c">
       <Filter>src\core\json</Filter>
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\proto\grpc\lb\v0\load_balancer.pb.c">
+      <Filter>src\core\proto\grpc\lb\v0</Filter>
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\surface\alarm.c">
       <Filter>src\core\surface</Filter>
     </ClCompile>
@@ -394,7 +400,7 @@
     <ClCompile Include="$(SolutionDir)\..\src\core\census\initialize.c">
       <Filter>src\core\census</Filter>
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\census\log.c">
+    <ClCompile Include="$(SolutionDir)\..\src\core\census\mlog.c">
       <Filter>src\core\census</Filter>
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\census\operation.c">
@@ -406,6 +412,15 @@
     <ClCompile Include="$(SolutionDir)\..\src\core\census\tracing.c">
       <Filter>src\core\census</Filter>
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\third_party\nanopb\pb_common.c">
+      <Filter>third_party\nanopb</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\third_party\nanopb\pb_decode.c">
+      <Filter>third_party\nanopb</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\third_party\nanopb\pb_encode.c">
+      <Filter>third_party\nanopb</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="$(SolutionDir)\..\include\grpc\byte_buffer.h">
@@ -470,6 +485,9 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\client_config\initial_connect_string.h">
       <Filter>src\core\client_config</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\client_config\lb_policies\load_balancer_api.h">
+      <Filter>src\core\client_config\lb_policies</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\src\core\client_config\lb_policies\pick_first.h">
       <Filter>src\core\client_config\lb_policies</Filter>
     </ClInclude>
@@ -620,9 +638,6 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\iomgr\timer_heap.h">
       <Filter>src\core\iomgr</Filter>
     </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\src\core\iomgr\timer_internal.h">
-      <Filter>src\core\iomgr</Filter>
-    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\src\core\iomgr\udp_server.h">
       <Filter>src\core\iomgr</Filter>
     </ClInclude>
@@ -653,6 +668,9 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\json\json_writer.h">
       <Filter>src\core\json</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\proto\grpc\lb\v0\load_balancer.pb.h">
+      <Filter>src\core\proto\grpc\lb\v0</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\src\core\statistics\census_interface.h">
       <Filter>src\core\statistics</Filter>
     </ClInclude>
@@ -773,12 +791,24 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\census\aggregation.h">
       <Filter>src\core\census</Filter>
     </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\src\core\census\log.h">
+    <ClInclude Include="$(SolutionDir)\..\src\core\census\mlog.h">
       <Filter>src\core\census</Filter>
     </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\src\core\census\rpc_metric_id.h">
       <Filter>src\core\census</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\third_party\nanopb\pb.h">
+      <Filter>third_party\nanopb</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\third_party\nanopb\pb_common.h">
+      <Filter>third_party\nanopb</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\third_party\nanopb\pb_decode.h">
+      <Filter>third_party\nanopb</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\third_party\nanopb\pb_encode.h">
+      <Filter>third_party\nanopb</Filter>
+    </ClInclude>
   </ItemGroup>
 
   <ItemGroup>
@@ -824,6 +854,18 @@
     <Filter Include="src\core\json">
       <UniqueIdentifier>{443ffc61-1bea-2477-6e54-1ddf8c139264}</UniqueIdentifier>
     </Filter>
+    <Filter Include="src\core\proto">
+      <UniqueIdentifier>{7f4bb22a-65ba-0f8f-6387-66b1f6677a80}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\core\proto\grpc">
+      <UniqueIdentifier>{9c2bd164-c317-8a13-564d-3b28b0fd79cf}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\core\proto\grpc\lb">
+      <UniqueIdentifier>{2bad8e10-4fc5-d8b3-e026-4abbd0c25cda}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\core\proto\grpc\lb\v0">
+      <UniqueIdentifier>{4475c8ed-e01b-8906-47d0-8a504189c0d5}</UniqueIdentifier>
+    </Filter>
     <Filter Include="src\core\statistics">
       <UniqueIdentifier>{e084164c-a069-00e3-db35-4e0b1cd6f0b7}</UniqueIdentifier>
     </Filter>
@@ -836,6 +878,12 @@
     <Filter Include="src\core\transport\chttp2">
       <UniqueIdentifier>{5fcd6206-f774-9ae6-4b85-305d6a723843}</UniqueIdentifier>
     </Filter>
+    <Filter Include="third_party">
+      <UniqueIdentifier>{025c051e-8eba-125b-67f9-173f95176eb2}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="third_party\nanopb">
+      <UniqueIdentifier>{6511f77d-f28c-80e0-0889-8975e688e344}</UniqueIdentifier>
+    </Filter>
   </ItemGroup>
 </Project>
 
diff --git a/vsprojects/vcxproj/interop_server_main/interop_server_main.vcxproj b/vsprojects/vcxproj/interop_server_main/interop_server_main.vcxproj
index 69f80a8..075750a 100644
--- a/vsprojects/vcxproj/interop_server_main/interop_server_main.vcxproj
+++ b/vsprojects/vcxproj/interop_server_main/interop_server_main.vcxproj
@@ -171,7 +171,7 @@
     </ClCompile>
     <ClInclude Include="$(SolutionDir)\..\src\proto\grpc\testing\test.grpc.pb.h">
     </ClInclude>
-    <ClCompile Include="$(SolutionDir)\..\test\cpp\interop\server.cc">
+    <ClCompile Include="$(SolutionDir)\..\test\cpp\interop\server_main.cc">
     </ClCompile>
   </ItemGroup>
   <ItemGroup>
diff --git a/vsprojects/vcxproj/interop_server_main/interop_server_main.vcxproj.filters b/vsprojects/vcxproj/interop_server_main/interop_server_main.vcxproj.filters
index 8a9ff27..51a6b9e 100644
--- a/vsprojects/vcxproj/interop_server_main/interop_server_main.vcxproj.filters
+++ b/vsprojects/vcxproj/interop_server_main/interop_server_main.vcxproj.filters
@@ -10,7 +10,7 @@
     <ClCompile Include="$(SolutionDir)\..\src\proto\grpc\testing\test.proto">
       <Filter>src\proto\grpc\testing</Filter>
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\test\cpp\interop\server.cc">
+    <ClCompile Include="$(SolutionDir)\..\test\cpp\interop\server_main.cc">
       <Filter>test\cpp\interop</Filter>
     </ClCompile>
   </ItemGroup>
diff --git a/vsprojects/vcxproj/qps/qps.vcxproj b/vsprojects/vcxproj/qps/qps.vcxproj
index 8306e2e..a57b740 100644
--- a/vsprojects/vcxproj/qps/qps.vcxproj
+++ b/vsprojects/vcxproj/qps/qps.vcxproj
@@ -157,7 +157,7 @@
     <ClInclude Include="$(SolutionDir)\..\test\cpp\qps\report.h" />
     <ClInclude Include="$(SolutionDir)\..\test\cpp\qps\server.h" />
     <ClInclude Include="$(SolutionDir)\..\test\cpp\qps\stats.h" />
-    <ClInclude Include="$(SolutionDir)\..\test\cpp\qps\timer.h" />
+    <ClInclude Include="$(SolutionDir)\..\test\cpp\qps\usage_timer.h" />
     <ClInclude Include="$(SolutionDir)\..\test\cpp\util\benchmark_config.h" />
   </ItemGroup>
   <ItemGroup>
@@ -227,7 +227,7 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\test\cpp\qps\server_sync.cc">
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\test\cpp\qps\timer.cc">
+    <ClCompile Include="$(SolutionDir)\..\test\cpp\qps\usage_timer.cc">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\test\cpp\util\benchmark_config.cc">
     </ClCompile>
diff --git a/vsprojects/vcxproj/qps/qps.vcxproj.filters b/vsprojects/vcxproj/qps/qps.vcxproj.filters
index 650116a..eeb9555 100644
--- a/vsprojects/vcxproj/qps/qps.vcxproj.filters
+++ b/vsprojects/vcxproj/qps/qps.vcxproj.filters
@@ -46,7 +46,7 @@
     <ClCompile Include="$(SolutionDir)\..\test\cpp\qps\server_sync.cc">
       <Filter>test\cpp\qps</Filter>
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\test\cpp\qps\timer.cc">
+    <ClCompile Include="$(SolutionDir)\..\test\cpp\qps\usage_timer.cc">
       <Filter>test\cpp\qps</Filter>
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\test\cpp\util\benchmark_config.cc">
@@ -84,7 +84,7 @@
     <ClInclude Include="$(SolutionDir)\..\test\cpp\qps\stats.h">
       <Filter>test\cpp\qps</Filter>
     </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\test\cpp\qps\timer.h">
+    <ClInclude Include="$(SolutionDir)\..\test\cpp\qps\usage_timer.h">
       <Filter>test\cpp\qps</Filter>
     </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\test\cpp\util\benchmark_config.h">
diff --git a/vsprojects/vcxproj/test/census_log_test/census_log_test.vcxproj b/vsprojects/vcxproj/test/census_log_test/census_log_test.vcxproj
deleted file mode 100644
index 851086d..0000000
--- a/vsprojects/vcxproj/test/census_log_test/census_log_test.vcxproj
+++ /dev/null
@@ -1,199 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <Import Project="$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies.openssl.props" Condition="Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\1.0.204.1.props')" />
-  <ItemGroup Label="ProjectConfigurations">
-    <ProjectConfiguration Include="Debug|Win32">
-      <Configuration>Debug</Configuration>
-      <Platform>Win32</Platform>
-    </ProjectConfiguration>
-    <ProjectConfiguration Include="Debug|x64">
-      <Configuration>Debug</Configuration>
-      <Platform>x64</Platform>
-    </ProjectConfiguration>
-    <ProjectConfiguration Include="Release|Win32">
-      <Configuration>Release</Configuration>
-      <Platform>Win32</Platform>
-    </ProjectConfiguration>
-    <ProjectConfiguration Include="Release|x64">
-      <Configuration>Release</Configuration>
-      <Platform>x64</Platform>
-    </ProjectConfiguration>
-  </ItemGroup>
-  <PropertyGroup Label="Globals">
-    <ProjectGuid>{C27CEE16-2BEC-5572-3956-677E9F6F8BED}</ProjectGuid>
-    <IgnoreWarnIntDirInTempDetected>true</IgnoreWarnIntDirInTempDetected>
-    <IntDir>$(SolutionDir)IntDir\$(MSBuildProjectName)\</IntDir>
-  </PropertyGroup>
-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
-  <PropertyGroup Condition="'$(VisualStudioVersion)' == '10.0'" Label="Configuration">
-    <PlatformToolset>v100</PlatformToolset>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(VisualStudioVersion)' == '11.0'" Label="Configuration">
-    <PlatformToolset>v110</PlatformToolset>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(VisualStudioVersion)' == '12.0'" Label="Configuration">
-    <PlatformToolset>v120</PlatformToolset>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(VisualStudioVersion)' == '14.0'" Label="Configuration">
-    <PlatformToolset>v140</PlatformToolset>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)'=='Debug'" Label="Configuration">
-    <ConfigurationType>Application</ConfigurationType>
-    <UseDebugLibraries>true</UseDebugLibraries>
-    <CharacterSet>Unicode</CharacterSet>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)'=='Release'" Label="Configuration">
-    <ConfigurationType>Application</ConfigurationType>
-    <UseDebugLibraries>false</UseDebugLibraries>
-    <WholeProgramOptimization>true</WholeProgramOptimization>
-    <CharacterSet>Unicode</CharacterSet>
-  </PropertyGroup>
-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
-  <ImportGroup Label="ExtensionSettings">
-  </ImportGroup>
-  <ImportGroup Label="PropertySheets">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
-    <Import Project="$(SolutionDir)\..\vsprojects\global.props" />
-    <Import Project="$(SolutionDir)\..\vsprojects\openssl.props" />
-    <Import Project="$(SolutionDir)\..\vsprojects\winsock.props" />
-    <Import Project="$(SolutionDir)\..\vsprojects\zlib.props" />
-  </ImportGroup>
-  <PropertyGroup Label="UserMacros" />
-  <PropertyGroup Condition="'$(Configuration)'=='Debug'">
-    <TargetName>census_log_test</TargetName>
-    <Linkage-grpc_dependencies_zlib>static</Linkage-grpc_dependencies_zlib>
-    <Configuration-grpc_dependencies_zlib>Debug</Configuration-grpc_dependencies_zlib>
-    <Linkage-grpc_dependencies_openssl>static</Linkage-grpc_dependencies_openssl>
-    <Configuration-grpc_dependencies_openssl>Debug</Configuration-grpc_dependencies_openssl>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)'=='Release'">
-    <TargetName>census_log_test</TargetName>
-    <Linkage-grpc_dependencies_zlib>static</Linkage-grpc_dependencies_zlib>
-    <Configuration-grpc_dependencies_zlib>Release</Configuration-grpc_dependencies_zlib>
-    <Linkage-grpc_dependencies_openssl>static</Linkage-grpc_dependencies_openssl>
-    <Configuration-grpc_dependencies_openssl>Release</Configuration-grpc_dependencies_openssl>
-  </PropertyGroup>
-    <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
-    <ClCompile>
-      <PrecompiledHeader>NotUsing</PrecompiledHeader>
-      <WarningLevel>Level3</WarningLevel>
-      <Optimization>Disabled</Optimization>
-      <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <SDLCheck>true</SDLCheck>
-      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
-      <TreatWarningAsError>true</TreatWarningAsError>
-      <DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat>
-      <MinimalRebuild Condition="$(Jenkins)">false</MinimalRebuild>
-    </ClCompile>
-    <Link>
-      <SubSystem>Console</SubSystem>
-      <GenerateDebugInformation Condition="!$(Jenkins)">true</GenerateDebugInformation>
-      <GenerateDebugInformation Condition="$(Jenkins)">false</GenerateDebugInformation>
-    </Link>
-  </ItemDefinitionGroup>
-
-    <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
-    <ClCompile>
-      <PrecompiledHeader>NotUsing</PrecompiledHeader>
-      <WarningLevel>Level3</WarningLevel>
-      <Optimization>Disabled</Optimization>
-      <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <SDLCheck>true</SDLCheck>
-      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
-      <TreatWarningAsError>true</TreatWarningAsError>
-      <DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat>
-      <MinimalRebuild Condition="$(Jenkins)">false</MinimalRebuild>
-    </ClCompile>
-    <Link>
-      <SubSystem>Console</SubSystem>
-      <GenerateDebugInformation Condition="!$(Jenkins)">true</GenerateDebugInformation>
-      <GenerateDebugInformation Condition="$(Jenkins)">false</GenerateDebugInformation>
-    </Link>
-  </ItemDefinitionGroup>
-
-    <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
-    <ClCompile>
-      <PrecompiledHeader>NotUsing</PrecompiledHeader>
-      <WarningLevel>Level3</WarningLevel>
-      <Optimization>MaxSpeed</Optimization>
-      <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <FunctionLevelLinking>true</FunctionLevelLinking>
-      <IntrinsicFunctions>true</IntrinsicFunctions>
-      <SDLCheck>true</SDLCheck>
-      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
-      <TreatWarningAsError>true</TreatWarningAsError>
-      <DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat>
-      <MinimalRebuild Condition="$(Jenkins)">false</MinimalRebuild>
-    </ClCompile>
-    <Link>
-      <SubSystem>Console</SubSystem>
-      <GenerateDebugInformation Condition="!$(Jenkins)">true</GenerateDebugInformation>
-      <GenerateDebugInformation Condition="$(Jenkins)">false</GenerateDebugInformation>
-      <EnableCOMDATFolding>true</EnableCOMDATFolding>
-      <OptimizeReferences>true</OptimizeReferences>
-    </Link>
-  </ItemDefinitionGroup>
-
-    <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
-    <ClCompile>
-      <PrecompiledHeader>NotUsing</PrecompiledHeader>
-      <WarningLevel>Level3</WarningLevel>
-      <Optimization>MaxSpeed</Optimization>
-      <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <FunctionLevelLinking>true</FunctionLevelLinking>
-      <IntrinsicFunctions>true</IntrinsicFunctions>
-      <SDLCheck>true</SDLCheck>
-      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
-      <TreatWarningAsError>true</TreatWarningAsError>
-      <DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat>
-      <MinimalRebuild Condition="$(Jenkins)">false</MinimalRebuild>
-    </ClCompile>
-    <Link>
-      <SubSystem>Console</SubSystem>
-      <GenerateDebugInformation Condition="!$(Jenkins)">true</GenerateDebugInformation>
-      <GenerateDebugInformation Condition="$(Jenkins)">false</GenerateDebugInformation>
-      <EnableCOMDATFolding>true</EnableCOMDATFolding>
-      <OptimizeReferences>true</OptimizeReferences>
-    </Link>
-  </ItemDefinitionGroup>
-
-  <ItemGroup>
-    <ClCompile Include="$(SolutionDir)\..\test\core\census\log_test.c">
-    </ClCompile>
-  </ItemGroup>
-  <ItemGroup>
-    <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\grpc_test_util\grpc_test_util.vcxproj">
-      <Project>{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}</Project>
-    </ProjectReference>
-    <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\grpc\grpc.vcxproj">
-      <Project>{29D16885-7228-4C31-81ED-5F9187C7F2A9}</Project>
-    </ProjectReference>
-    <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\gpr_test_util\gpr_test_util.vcxproj">
-      <Project>{EAB0A629-17A9-44DB-B5FF-E91A721FE037}</Project>
-    </ProjectReference>
-    <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\gpr\gpr.vcxproj">
-      <Project>{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}</Project>
-    </ProjectReference>
-  </ItemGroup>
-  <ItemGroup>
-    <None Include="packages.config" />
-  </ItemGroup>
-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
-  <ImportGroup Label="ExtensionTargets">
-  <Import Project="$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.10\build\native\grpc.dependencies.zlib.redist.targets" Condition="Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.10\build\native\grpc.dependencies\grpc.dependencies.zlib.targets')" />
-  <Import Project="$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.10\build\native\grpc.dependencies.zlib.targets" Condition="Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.10\build\native\grpc.dependencies\grpc.dependencies.zlib.targets')" />
-  <Import Project="$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.204.1\build\native\grpc.dependencies.openssl.redist.targets" Condition="Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.204.1\build\native\grpc.dependencies\grpc.dependencies.openssl.targets')" />
-  <Import Project="$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies.openssl.targets" Condition="Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies\grpc.dependencies.openssl.targets')" />
-  </ImportGroup>
-  <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
-    <PropertyGroup>
-      <ErrorText>This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them.  For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
-    </PropertyGroup>
-    <Error Condition="!Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.10\build\native\grpc.dependencies.zlib.redist.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.10\build\native\grpc.dependencies.zlib.redist.targets')" />
-    <Error Condition="!Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.10\build\native\grpc.dependencies.zlib.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.10\build\native\grpc.dependencies.zlib.targets')" />
-    <Error Condition="!Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.204.1\build\native\grpc.dependencies.openssl.redist.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.204.1\build\native\grpc.dependencies.openssl.redist.targets')" />
-    <Error Condition="!Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies.openssl.props')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies.openssl.props')" />
-    <Error Condition="!Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies.openssl.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies.openssl.targets')" />
-  </Target>
-</Project>
-
diff --git a/vsprojects/vcxproj/test/end2end/tests/end2end_nosec_tests/end2end_nosec_tests.vcxproj b/vsprojects/vcxproj/test/end2end/tests/end2end_nosec_tests/end2end_nosec_tests.vcxproj
index 50c1b61..2f3b591 100644
--- a/vsprojects/vcxproj/test/end2end/tests/end2end_nosec_tests/end2end_nosec_tests.vcxproj
+++ b/vsprojects/vcxproj/test/end2end/tests/end2end_nosec_tests/end2end_nosec_tests.vcxproj
@@ -169,12 +169,10 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\test\core\end2end\tests\cancel_with_status.c">
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\test\core\end2end\tests\channel_connectivity.c">
-    </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\test\core\end2end\tests\channel_ping.c">
-    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\test\core\end2end\tests\compressed_payload.c">
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\test\core\end2end\tests\connectivity.c">
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\test\core\end2end\tests\default_host.c">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\test\core\end2end\tests\disappearing_server.c">
@@ -195,14 +193,14 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\test\core\end2end\tests\max_message_length.c">
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\test\core\end2end\tests\metadata.c">
-    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\test\core\end2end\tests\negative_deadline.c">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\test\core\end2end\tests\no_op.c">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\test\core\end2end\tests\payload.c">
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\test\core\end2end\tests\ping.c">
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\test\core\end2end\tests\ping_pong_streaming.c">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\test\core\end2end\tests\registered_call.c">
@@ -219,6 +217,8 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\test\core\end2end\tests\simple_delayed_request.c">
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\test\core\end2end\tests\simple_metadata.c">
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\test\core\end2end\tests\simple_request.c">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\test\core\end2end\tests\trailing_metadata.c">
diff --git a/vsprojects/vcxproj/test/end2end/tests/end2end_nosec_tests/end2end_nosec_tests.vcxproj.filters b/vsprojects/vcxproj/test/end2end/tests/end2end_nosec_tests/end2end_nosec_tests.vcxproj.filters
index a825a2d..c63ebe7 100644
--- a/vsprojects/vcxproj/test/end2end/tests/end2end_nosec_tests/end2end_nosec_tests.vcxproj.filters
+++ b/vsprojects/vcxproj/test/end2end/tests/end2end_nosec_tests/end2end_nosec_tests.vcxproj.filters
@@ -28,15 +28,12 @@
     <ClCompile Include="$(SolutionDir)\..\test\core\end2end\tests\cancel_with_status.c">
       <Filter>test\core\end2end\tests</Filter>
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\test\core\end2end\tests\channel_connectivity.c">
-      <Filter>test\core\end2end\tests</Filter>
-    </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\test\core\end2end\tests\channel_ping.c">
-      <Filter>test\core\end2end\tests</Filter>
-    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\test\core\end2end\tests\compressed_payload.c">
       <Filter>test\core\end2end\tests</Filter>
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\test\core\end2end\tests\connectivity.c">
+      <Filter>test\core\end2end\tests</Filter>
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\test\core\end2end\tests\default_host.c">
       <Filter>test\core\end2end\tests</Filter>
     </ClCompile>
@@ -67,9 +64,6 @@
     <ClCompile Include="$(SolutionDir)\..\test\core\end2end\tests\max_message_length.c">
       <Filter>test\core\end2end\tests</Filter>
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\test\core\end2end\tests\metadata.c">
-      <Filter>test\core\end2end\tests</Filter>
-    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\test\core\end2end\tests\negative_deadline.c">
       <Filter>test\core\end2end\tests</Filter>
     </ClCompile>
@@ -79,6 +73,9 @@
     <ClCompile Include="$(SolutionDir)\..\test\core\end2end\tests\payload.c">
       <Filter>test\core\end2end\tests</Filter>
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\test\core\end2end\tests\ping.c">
+      <Filter>test\core\end2end\tests</Filter>
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\test\core\end2end\tests\ping_pong_streaming.c">
       <Filter>test\core\end2end\tests</Filter>
     </ClCompile>
@@ -103,6 +100,9 @@
     <ClCompile Include="$(SolutionDir)\..\test\core\end2end\tests\simple_delayed_request.c">
       <Filter>test\core\end2end\tests</Filter>
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\test\core\end2end\tests\simple_metadata.c">
+      <Filter>test\core\end2end\tests</Filter>
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\test\core\end2end\tests\simple_request.c">
       <Filter>test\core\end2end\tests</Filter>
     </ClCompile>
diff --git a/vsprojects/vcxproj/test/end2end/tests/end2end_tests/end2end_tests.vcxproj b/vsprojects/vcxproj/test/end2end/tests/end2end_tests/end2end_tests.vcxproj
index fa559e1..9d7bdc5 100644
--- a/vsprojects/vcxproj/test/end2end/tests/end2end_tests/end2end_tests.vcxproj
+++ b/vsprojects/vcxproj/test/end2end/tests/end2end_tests/end2end_tests.vcxproj
@@ -171,12 +171,10 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\test\core\end2end\tests\cancel_with_status.c">
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\test\core\end2end\tests\channel_connectivity.c">
-    </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\test\core\end2end\tests\channel_ping.c">
-    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\test\core\end2end\tests\compressed_payload.c">
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\test\core\end2end\tests\connectivity.c">
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\test\core\end2end\tests\default_host.c">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\test\core\end2end\tests\disappearing_server.c">
@@ -197,14 +195,14 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\test\core\end2end\tests\max_message_length.c">
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\test\core\end2end\tests\metadata.c">
-    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\test\core\end2end\tests\negative_deadline.c">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\test\core\end2end\tests\no_op.c">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\test\core\end2end\tests\payload.c">
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\test\core\end2end\tests\ping.c">
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\test\core\end2end\tests\ping_pong_streaming.c">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\test\core\end2end\tests\registered_call.c">
@@ -221,6 +219,8 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\test\core\end2end\tests\simple_delayed_request.c">
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\test\core\end2end\tests\simple_metadata.c">
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\test\core\end2end\tests\simple_request.c">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\test\core\end2end\tests\trailing_metadata.c">
diff --git a/vsprojects/vcxproj/test/end2end/tests/end2end_tests/end2end_tests.vcxproj.filters b/vsprojects/vcxproj/test/end2end/tests/end2end_tests/end2end_tests.vcxproj.filters
index 61afa17..c30054a 100644
--- a/vsprojects/vcxproj/test/end2end/tests/end2end_tests/end2end_tests.vcxproj.filters
+++ b/vsprojects/vcxproj/test/end2end/tests/end2end_tests/end2end_tests.vcxproj.filters
@@ -31,15 +31,12 @@
     <ClCompile Include="$(SolutionDir)\..\test\core\end2end\tests\cancel_with_status.c">
       <Filter>test\core\end2end\tests</Filter>
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\test\core\end2end\tests\channel_connectivity.c">
-      <Filter>test\core\end2end\tests</Filter>
-    </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\test\core\end2end\tests\channel_ping.c">
-      <Filter>test\core\end2end\tests</Filter>
-    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\test\core\end2end\tests\compressed_payload.c">
       <Filter>test\core\end2end\tests</Filter>
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\test\core\end2end\tests\connectivity.c">
+      <Filter>test\core\end2end\tests</Filter>
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\test\core\end2end\tests\default_host.c">
       <Filter>test\core\end2end\tests</Filter>
     </ClCompile>
@@ -70,9 +67,6 @@
     <ClCompile Include="$(SolutionDir)\..\test\core\end2end\tests\max_message_length.c">
       <Filter>test\core\end2end\tests</Filter>
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\test\core\end2end\tests\metadata.c">
-      <Filter>test\core\end2end\tests</Filter>
-    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\test\core\end2end\tests\negative_deadline.c">
       <Filter>test\core\end2end\tests</Filter>
     </ClCompile>
@@ -82,6 +76,9 @@
     <ClCompile Include="$(SolutionDir)\..\test\core\end2end\tests\payload.c">
       <Filter>test\core\end2end\tests</Filter>
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\test\core\end2end\tests\ping.c">
+      <Filter>test\core\end2end\tests</Filter>
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\test\core\end2end\tests\ping_pong_streaming.c">
       <Filter>test\core\end2end\tests</Filter>
     </ClCompile>
@@ -106,6 +103,9 @@
     <ClCompile Include="$(SolutionDir)\..\test\core\end2end\tests\simple_delayed_request.c">
       <Filter>test\core\end2end\tests</Filter>
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\test\core\end2end\tests\simple_metadata.c">
+      <Filter>test\core\end2end\tests</Filter>
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\test\core\end2end\tests\simple_request.c">
       <Filter>test\core\end2end\tests</Filter>
     </ClCompile>
diff --git a/vsprojects/vcxproj/test/gpr_file_test/gpr_file_test.vcxproj b/vsprojects/vcxproj/test/gpr_load_file_test/gpr_load_file_test.vcxproj
similarity index 97%
rename from vsprojects/vcxproj/test/gpr_file_test/gpr_file_test.vcxproj
rename to vsprojects/vcxproj/test/gpr_load_file_test/gpr_load_file_test.vcxproj
index 5a2fdee..4182969 100644
--- a/vsprojects/vcxproj/test/gpr_file_test/gpr_file_test.vcxproj
+++ b/vsprojects/vcxproj/test/gpr_load_file_test/gpr_load_file_test.vcxproj
@@ -20,7 +20,7 @@
     </ProjectConfiguration>
   </ItemGroup>
   <PropertyGroup Label="Globals">
-    <ProjectGuid>{13B0BA63-A3A4-D0E7-1DF2-C73281EB0678}</ProjectGuid>
+    <ProjectGuid>{B36DE5B4-8B73-1194-7539-974D9524D609}</ProjectGuid>
     <IgnoreWarnIntDirInTempDetected>true</IgnoreWarnIntDirInTempDetected>
     <IntDir>$(SolutionDir)IntDir\$(MSBuildProjectName)\</IntDir>
   </PropertyGroup>
@@ -60,14 +60,14 @@
   </ImportGroup>
   <PropertyGroup Label="UserMacros" />
   <PropertyGroup Condition="'$(Configuration)'=='Debug'">
-    <TargetName>gpr_file_test</TargetName>
+    <TargetName>gpr_load_file_test</TargetName>
     <Linkage-grpc_dependencies_zlib>static</Linkage-grpc_dependencies_zlib>
     <Configuration-grpc_dependencies_zlib>Debug</Configuration-grpc_dependencies_zlib>
     <Linkage-grpc_dependencies_openssl>static</Linkage-grpc_dependencies_openssl>
     <Configuration-grpc_dependencies_openssl>Debug</Configuration-grpc_dependencies_openssl>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)'=='Release'">
-    <TargetName>gpr_file_test</TargetName>
+    <TargetName>gpr_load_file_test</TargetName>
     <Linkage-grpc_dependencies_zlib>static</Linkage-grpc_dependencies_zlib>
     <Configuration-grpc_dependencies_zlib>Release</Configuration-grpc_dependencies_zlib>
     <Linkage-grpc_dependencies_openssl>static</Linkage-grpc_dependencies_openssl>
@@ -158,7 +158,7 @@
   </ItemDefinitionGroup>
 
   <ItemGroup>
-    <ClCompile Include="$(SolutionDir)\..\test\core\support\file_test.c">
+    <ClCompile Include="$(SolutionDir)\..\test\core\support\load_file_test.c">
     </ClCompile>
   </ItemGroup>
   <ItemGroup>
diff --git a/vsprojects/vcxproj/test/gpr_file_test/gpr_file_test.vcxproj.filters b/vsprojects/vcxproj/test/gpr_load_file_test/gpr_load_file_test.vcxproj.filters
similarity index 62%
rename from vsprojects/vcxproj/test/gpr_file_test/gpr_file_test.vcxproj.filters
rename to vsprojects/vcxproj/test/gpr_load_file_test/gpr_load_file_test.vcxproj.filters
index ec225bd..0edd0fe 100644
--- a/vsprojects/vcxproj/test/gpr_file_test/gpr_file_test.vcxproj.filters
+++ b/vsprojects/vcxproj/test/gpr_load_file_test/gpr_load_file_test.vcxproj.filters
@@ -1,20 +1,20 @@
 <?xml version="1.0" encoding="utf-8"?>
 <Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
   <ItemGroup>
-    <ClCompile Include="$(SolutionDir)\..\test\core\support\file_test.c">
+    <ClCompile Include="$(SolutionDir)\..\test\core\support\load_file_test.c">
       <Filter>test\core\support</Filter>
     </ClCompile>
   </ItemGroup>
 
   <ItemGroup>
     <Filter Include="test">
-      <UniqueIdentifier>{ea0f8f5c-afe0-ed4b-ae64-d98a8f32a9e1}</UniqueIdentifier>
+      <UniqueIdentifier>{7defb822-a4cc-a221-8900-1041a6c2c134}</UniqueIdentifier>
     </Filter>
     <Filter Include="test\core">
-      <UniqueIdentifier>{2ac0488e-8ef6-c61d-96c0-9cf580283589}</UniqueIdentifier>
+      <UniqueIdentifier>{3f3cae49-1efd-7015-0fa1-5621168945d5}</UniqueIdentifier>
     </Filter>
     <Filter Include="test\core\support">
-      <UniqueIdentifier>{d2feffa9-e47c-ec2c-ecce-caf8ce85cb08}</UniqueIdentifier>
+      <UniqueIdentifier>{54e9b9b9-021a-139b-53f2-2f8b7173306c}</UniqueIdentifier>
     </Filter>
   </ItemGroup>
 </Project>
diff --git a/vsprojects/vcxproj/test/grpc_base64_test/grpc_base64_test.vcxproj b/vsprojects/vcxproj/test/grpc_b64_test/grpc_b64_test.vcxproj
similarity index 97%
rename from vsprojects/vcxproj/test/grpc_base64_test/grpc_base64_test.vcxproj
rename to vsprojects/vcxproj/test/grpc_b64_test/grpc_b64_test.vcxproj
index 3e49ac8..7e6b4df 100644
--- a/vsprojects/vcxproj/test/grpc_base64_test/grpc_base64_test.vcxproj
+++ b/vsprojects/vcxproj/test/grpc_b64_test/grpc_b64_test.vcxproj
@@ -20,7 +20,7 @@
     </ProjectConfiguration>
   </ItemGroup>
   <PropertyGroup Label="Globals">
-    <ProjectGuid>{759A2BB1-DA1B-196C-94A3-98687BBC9F36}</ProjectGuid>
+    <ProjectGuid>{A19FD81D-DF19-B8A4-4A8A-6967217FEC85}</ProjectGuid>
     <IgnoreWarnIntDirInTempDetected>true</IgnoreWarnIntDirInTempDetected>
     <IntDir>$(SolutionDir)IntDir\$(MSBuildProjectName)\</IntDir>
   </PropertyGroup>
@@ -60,14 +60,14 @@
   </ImportGroup>
   <PropertyGroup Label="UserMacros" />
   <PropertyGroup Condition="'$(Configuration)'=='Debug'">
-    <TargetName>grpc_base64_test</TargetName>
+    <TargetName>grpc_b64_test</TargetName>
     <Linkage-grpc_dependencies_zlib>static</Linkage-grpc_dependencies_zlib>
     <Configuration-grpc_dependencies_zlib>Debug</Configuration-grpc_dependencies_zlib>
     <Linkage-grpc_dependencies_openssl>static</Linkage-grpc_dependencies_openssl>
     <Configuration-grpc_dependencies_openssl>Debug</Configuration-grpc_dependencies_openssl>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)'=='Release'">
-    <TargetName>grpc_base64_test</TargetName>
+    <TargetName>grpc_b64_test</TargetName>
     <Linkage-grpc_dependencies_zlib>static</Linkage-grpc_dependencies_zlib>
     <Configuration-grpc_dependencies_zlib>Release</Configuration-grpc_dependencies_zlib>
     <Linkage-grpc_dependencies_openssl>static</Linkage-grpc_dependencies_openssl>
@@ -158,7 +158,7 @@
   </ItemDefinitionGroup>
 
   <ItemGroup>
-    <ClCompile Include="$(SolutionDir)\..\test\core\security\base64_test.c">
+    <ClCompile Include="$(SolutionDir)\..\test\core\security\b64_test.c">
     </ClCompile>
   </ItemGroup>
   <ItemGroup>
diff --git a/vsprojects/vcxproj/test/grpc_base64_test/grpc_base64_test.vcxproj.filters b/vsprojects/vcxproj/test/grpc_b64_test/grpc_b64_test.vcxproj.filters
similarity index 62%
rename from vsprojects/vcxproj/test/grpc_base64_test/grpc_base64_test.vcxproj.filters
rename to vsprojects/vcxproj/test/grpc_b64_test/grpc_b64_test.vcxproj.filters
index 6db15df..4335011 100644
--- a/vsprojects/vcxproj/test/grpc_base64_test/grpc_base64_test.vcxproj.filters
+++ b/vsprojects/vcxproj/test/grpc_b64_test/grpc_b64_test.vcxproj.filters
@@ -1,20 +1,20 @@
 <?xml version="1.0" encoding="utf-8"?>
 <Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
   <ItemGroup>
-    <ClCompile Include="$(SolutionDir)\..\test\core\security\base64_test.c">
+    <ClCompile Include="$(SolutionDir)\..\test\core\security\b64_test.c">
       <Filter>test\core\security</Filter>
     </ClCompile>
   </ItemGroup>
 
   <ItemGroup>
     <Filter Include="test">
-      <UniqueIdentifier>{a996936d-cc5f-01b6-024a-8c48e97621a1}</UniqueIdentifier>
+      <UniqueIdentifier>{61d5c8e1-ac27-5bd0-d581-aeb585f0157e}</UniqueIdentifier>
     </Filter>
     <Filter Include="test\core">
-      <UniqueIdentifier>{f24de076-eae7-0bf0-1028-c08488419d68}</UniqueIdentifier>
+      <UniqueIdentifier>{409b4a57-584c-1dc5-db72-1e8d4c462e9d}</UniqueIdentifier>
     </Filter>
     <Filter Include="test\core\security">
-      <UniqueIdentifier>{4e36400d-5525-a04f-f6bf-4960c950aa00}</UniqueIdentifier>
+      <UniqueIdentifier>{0cb2c3ef-ed46-78ae-140c-29f21dc6fdb1}</UniqueIdentifier>
     </Filter>
   </ItemGroup>
 </Project>
diff --git a/vsprojects/vcxproj/test/grpc_base64_test/grpc_base64_test.vcxproj b/vsprojects/vcxproj/test/grpclb_api_test/grpclb_api_test.vcxproj
similarity index 92%
copy from vsprojects/vcxproj/test/grpc_base64_test/grpc_base64_test.vcxproj
copy to vsprojects/vcxproj/test/grpclb_api_test/grpclb_api_test.vcxproj
index 3e49ac8..1509ece 100644
--- a/vsprojects/vcxproj/test/grpc_base64_test/grpc_base64_test.vcxproj
+++ b/vsprojects/vcxproj/test/grpclb_api_test/grpclb_api_test.vcxproj
@@ -20,7 +20,7 @@
     </ProjectConfiguration>
   </ItemGroup>
   <PropertyGroup Label="Globals">
-    <ProjectGuid>{759A2BB1-DA1B-196C-94A3-98687BBC9F36}</ProjectGuid>
+    <ProjectGuid>{990AF023-17D7-8DBF-EB6E-14C7C016C77E}</ProjectGuid>
     <IgnoreWarnIntDirInTempDetected>true</IgnoreWarnIntDirInTempDetected>
     <IntDir>$(SolutionDir)IntDir\$(MSBuildProjectName)\</IntDir>
   </PropertyGroup>
@@ -53,21 +53,23 @@
   </ImportGroup>
   <ImportGroup Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="$(SolutionDir)\..\vsprojects\cpptest.props" />
     <Import Project="$(SolutionDir)\..\vsprojects\global.props" />
     <Import Project="$(SolutionDir)\..\vsprojects\openssl.props" />
+    <Import Project="$(SolutionDir)\..\vsprojects\protobuf.props" />
     <Import Project="$(SolutionDir)\..\vsprojects\winsock.props" />
     <Import Project="$(SolutionDir)\..\vsprojects\zlib.props" />
   </ImportGroup>
   <PropertyGroup Label="UserMacros" />
   <PropertyGroup Condition="'$(Configuration)'=='Debug'">
-    <TargetName>grpc_base64_test</TargetName>
+    <TargetName>grpclb_api_test</TargetName>
     <Linkage-grpc_dependencies_zlib>static</Linkage-grpc_dependencies_zlib>
     <Configuration-grpc_dependencies_zlib>Debug</Configuration-grpc_dependencies_zlib>
     <Linkage-grpc_dependencies_openssl>static</Linkage-grpc_dependencies_openssl>
     <Configuration-grpc_dependencies_openssl>Debug</Configuration-grpc_dependencies_openssl>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)'=='Release'">
-    <TargetName>grpc_base64_test</TargetName>
+    <TargetName>grpclb_api_test</TargetName>
     <Linkage-grpc_dependencies_zlib>static</Linkage-grpc_dependencies_zlib>
     <Configuration-grpc_dependencies_zlib>Release</Configuration-grpc_dependencies_zlib>
     <Linkage-grpc_dependencies_openssl>static</Linkage-grpc_dependencies_openssl>
@@ -158,22 +160,30 @@
   </ItemDefinitionGroup>
 
   <ItemGroup>
-    <ClCompile Include="$(SolutionDir)\..\test\core\security\base64_test.c">
+    <ClCompile Include="$(SolutionDir)\..\src\proto\grpc\lb\v0\load_balancer.pb.cc">
+    </ClCompile>
+    <ClInclude Include="$(SolutionDir)\..\src\proto\grpc\lb\v0\load_balancer.pb.h">
+    </ClInclude>
+    <ClCompile Include="$(SolutionDir)\..\src\proto\grpc\lb\v0\load_balancer.grpc.pb.cc">
+    </ClCompile>
+    <ClInclude Include="$(SolutionDir)\..\src\proto\grpc\lb\v0\load_balancer.grpc.pb.h">
+    </ClInclude>
+    <ClCompile Include="$(SolutionDir)\..\test\cpp\grpclb\grpclb_api_test.cc">
     </ClCompile>
   </ItemGroup>
   <ItemGroup>
+    <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\grpc++_test_util\grpc++_test_util.vcxproj">
+      <Project>{0BE77741-552A-929B-A497-4EF7ECE17A64}</Project>
+    </ProjectReference>
     <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\grpc_test_util\grpc_test_util.vcxproj">
       <Project>{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}</Project>
     </ProjectReference>
+    <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\grpc++\grpc++.vcxproj">
+      <Project>{C187A093-A0FE-489D-A40A-6E33DE0F9FEB}</Project>
+    </ProjectReference>
     <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\grpc\grpc.vcxproj">
       <Project>{29D16885-7228-4C31-81ED-5F9187C7F2A9}</Project>
     </ProjectReference>
-    <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\gpr_test_util\gpr_test_util.vcxproj">
-      <Project>{EAB0A629-17A9-44DB-B5FF-E91A721FE037}</Project>
-    </ProjectReference>
-    <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\gpr\gpr.vcxproj">
-      <Project>{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}</Project>
-    </ProjectReference>
   </ItemGroup>
   <ItemGroup>
     <None Include="packages.config" />
diff --git a/vsprojects/vcxproj/test/grpclb_api_test/grpclb_api_test.vcxproj.filters b/vsprojects/vcxproj/test/grpclb_api_test/grpclb_api_test.vcxproj.filters
new file mode 100644
index 0000000..6c57b8c
--- /dev/null
+++ b/vsprojects/vcxproj/test/grpclb_api_test/grpclb_api_test.vcxproj.filters
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup>
+    <ClCompile Include="$(SolutionDir)\..\src\proto\grpc\lb\v0\load_balancer.proto">
+      <Filter>src\proto\grpc\lb\v0</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\test\cpp\grpclb\grpclb_api_test.cc">
+      <Filter>test\cpp\grpclb</Filter>
+    </ClCompile>
+  </ItemGroup>
+
+  <ItemGroup>
+    <Filter Include="src">
+      <UniqueIdentifier>{a31d21fb-c6ab-75ce-43dc-7d6f506765e6}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\proto">
+      <UniqueIdentifier>{10d49c90-8503-9b10-6678-eed983bc25d9}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\proto\grpc">
+      <UniqueIdentifier>{8b6be783-e071-44cc-2096-f1c476012556}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\proto\grpc\lb">
+      <UniqueIdentifier>{2981699e-c196-c599-bc17-c177770f89ee}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\proto\grpc\lb\v0">
+      <UniqueIdentifier>{3d04774a-1c2f-e100-435e-08af5d539250}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="test">
+      <UniqueIdentifier>{64736e1d-eb77-664f-34ab-6cf41263d3d8}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="test\cpp">
+      <UniqueIdentifier>{c86e9cb1-bed4-3697-40f2-9ecff6297fa5}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="test\cpp\grpclb">
+      <UniqueIdentifier>{6b5ba83a-6cf2-5a7b-0ab8-62de31882705}</UniqueIdentifier>
+    </Filter>
+  </ItemGroup>
+</Project>
+
diff --git a/vsprojects/vcxproj/test/grpc_base64_test/grpc_base64_test.vcxproj b/vsprojects/vcxproj/test/mlog_test/mlog_test.vcxproj
similarity index 97%
copy from vsprojects/vcxproj/test/grpc_base64_test/grpc_base64_test.vcxproj
copy to vsprojects/vcxproj/test/mlog_test/mlog_test.vcxproj
index 3e49ac8..44b9a97 100644
--- a/vsprojects/vcxproj/test/grpc_base64_test/grpc_base64_test.vcxproj
+++ b/vsprojects/vcxproj/test/mlog_test/mlog_test.vcxproj
@@ -20,7 +20,7 @@
     </ProjectConfiguration>
   </ItemGroup>
   <PropertyGroup Label="Globals">
-    <ProjectGuid>{759A2BB1-DA1B-196C-94A3-98687BBC9F36}</ProjectGuid>
+    <ProjectGuid>{9345E329-80F3-DED4-FDC3-BF63FCEA2C03}</ProjectGuid>
     <IgnoreWarnIntDirInTempDetected>true</IgnoreWarnIntDirInTempDetected>
     <IntDir>$(SolutionDir)IntDir\$(MSBuildProjectName)\</IntDir>
   </PropertyGroup>
@@ -60,14 +60,14 @@
   </ImportGroup>
   <PropertyGroup Label="UserMacros" />
   <PropertyGroup Condition="'$(Configuration)'=='Debug'">
-    <TargetName>grpc_base64_test</TargetName>
+    <TargetName>mlog_test</TargetName>
     <Linkage-grpc_dependencies_zlib>static</Linkage-grpc_dependencies_zlib>
     <Configuration-grpc_dependencies_zlib>Debug</Configuration-grpc_dependencies_zlib>
     <Linkage-grpc_dependencies_openssl>static</Linkage-grpc_dependencies_openssl>
     <Configuration-grpc_dependencies_openssl>Debug</Configuration-grpc_dependencies_openssl>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)'=='Release'">
-    <TargetName>grpc_base64_test</TargetName>
+    <TargetName>mlog_test</TargetName>
     <Linkage-grpc_dependencies_zlib>static</Linkage-grpc_dependencies_zlib>
     <Configuration-grpc_dependencies_zlib>Release</Configuration-grpc_dependencies_zlib>
     <Linkage-grpc_dependencies_openssl>static</Linkage-grpc_dependencies_openssl>
@@ -158,7 +158,7 @@
   </ItemDefinitionGroup>
 
   <ItemGroup>
-    <ClCompile Include="$(SolutionDir)\..\test\core\security\base64_test.c">
+    <ClCompile Include="$(SolutionDir)\..\test\core\census\mlog_test.c">
     </ClCompile>
   </ItemGroup>
   <ItemGroup>
diff --git a/vsprojects/vcxproj/test/census_log_test/census_log_test.vcxproj.filters b/vsprojects/vcxproj/test/mlog_test/mlog_test.vcxproj.filters
similarity index 63%
rename from vsprojects/vcxproj/test/census_log_test/census_log_test.vcxproj.filters
rename to vsprojects/vcxproj/test/mlog_test/mlog_test.vcxproj.filters
index 135c778..982dedd 100644
--- a/vsprojects/vcxproj/test/census_log_test/census_log_test.vcxproj.filters
+++ b/vsprojects/vcxproj/test/mlog_test/mlog_test.vcxproj.filters
@@ -1,20 +1,20 @@
 <?xml version="1.0" encoding="utf-8"?>
 <Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
   <ItemGroup>
-    <ClCompile Include="$(SolutionDir)\..\test\core\census\log_test.c">
+    <ClCompile Include="$(SolutionDir)\..\test\core\census\mlog_test.c">
       <Filter>test\core\census</Filter>
     </ClCompile>
   </ItemGroup>
 
   <ItemGroup>
     <Filter Include="test">
-      <UniqueIdentifier>{4d0aae38-6975-cafb-30a6-a7c2c87d22ff}</UniqueIdentifier>
+      <UniqueIdentifier>{cf4f3b02-7a43-f5b5-708a-938b179be26e}</UniqueIdentifier>
     </Filter>
     <Filter Include="test\core">
-      <UniqueIdentifier>{fb85321f-d3b5-ef2f-c5aa-34660a5e0c7b}</UniqueIdentifier>
+      <UniqueIdentifier>{74b31c41-bf60-9274-a718-f33cd7c659b4}</UniqueIdentifier>
     </Filter>
     <Filter Include="test\core\census">
-      <UniqueIdentifier>{f23141da-cbe2-70fa-8207-858af868eb18}</UniqueIdentifier>
+      <UniqueIdentifier>{2117a367-a751-9526-028f-07b5e88f7037}</UniqueIdentifier>
     </Filter>
   </ItemGroup>
 </Project>